From b02bb98ffea2c376ba67eb049b8ba6b04d76e084 Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Thu, 28 Feb 2002 21:36:40 +0100
Subject: [PATCH] release: 1.5.35

---
 ChangeLog                                  | 61 +++++++++++++++++
 Documentation/regression-test.tely         |  9 ++-
 Documentation/user/refman.itely            | 23 ++-----
 NEWS                                       |  4 +-
 VERSION                                    |  2 +-
 input/regression/beam-over-barline.ly      |  6 ++
 input/regression/beaming-ternary-metrum.ly | 10 +++
 input/regression/figured-bass.ly           | 25 +++++++
 lily/bass-figure.cc                        |  7 ++
 lily/collision.cc                          |  9 ++-
 lily/command-request.cc                    |  2 +-
 lily/engraver-group-engraver.cc            | 32 ++++++++-
 lily/figured-bass-engraver.cc              | 43 +++---------
 lily/font-interface.cc                     | 19 ++++++
 lily/font-metric.cc                        | 22 +++++++
 lily/grob.cc                               | 37 +++--------
 lily/include/lily-guile.hh                 |  1 +
 lily/include/lookup.hh                     |  1 +
 lily/include/musical-request.hh            |  6 ++
 lily/lexer.ll                              |  9 +++
 lily/lily-guile.cc                         | 17 +++--
 lily/lookup.cc                             | 55 ++++++++++++++--
 lily/molecule.cc                           | 77 ++++++++++++++--------
 lily/music.cc                              |  2 +-
 lily/parser.yy                             | 51 +++++++++-----
 lily/scm-option.cc                         | 12 ++--
 lily/span-arpeggio-engraver.cc             |  2 +-
 lily/stem-engraver.cc                      |  4 +-
 lily/system-start-delimiter.cc             | 14 ++--
 lily/third-try.cc                          |  8 ++-
 lily/translator-group.cc                   |  2 +-
 make/out/lilypond.lsm                      |  8 +--
 make/out/lilypond.mandrake.spec            |  2 +-
 make/out/lilypond.redhat.spec              |  4 +-
 make/out/lilypond.suse.spec                |  4 +-
 mf/feta-nummer-code.mf                     |  4 ++
 mf/feta-nummer.mf                          |  5 ++
 mf/feta-nummer12.mf                        |  2 +
 mf/parmesan-generic.mf                     | 12 ++--
 mf/parmesan-heads.mf                       | 49 ++++++++++----
 mf/parmesan-scripts.mf                     | 46 +++++++++++++
 scm/bass-figure.scm                        | 64 ++++++++++++++++++
 scm/grob-description.scm                   | 12 +---
 scm/grob-property-description.scm          |  4 ++
 scm/lily.scm                               |  9 +++
 scm/music-property-description.scm         |  9 ++-
 scm/output-lib.scm                         |  5 +-
 scm/tex.scm                                |  2 +-
 48 files changed, 613 insertions(+), 200 deletions(-)
 create mode 100644 input/regression/beam-over-barline.ly
 create mode 100644 input/regression/beaming-ternary-metrum.ly
 create mode 100644 input/regression/figured-bass.ly
 create mode 100644 lily/bass-figure.cc
 create mode 100644 mf/feta-nummer12.mf
 create mode 100644 mf/parmesan-scripts.mf
 create mode 100644 scm/bass-figure.scm

diff --git a/ChangeLog b/ChangeLog
index c8671a34e7..83eeee5a6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,63 @@
+2002-02-28  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
+
+	* VERSION (PATCH_LEVEL): 1.5.35 released.
+
+	* lily/lookup.cc (ly_bracket): Scheme function ly-bracket
+	(bracket): New function.
+
+	* lily/stem-engraver.cc (stop_translation_timestep): bugfix, unset
+	stemLeftBeamCount, stemRightBeamCount in stead of using #<undefined> 
+
+	* lily/third-try.cc (set_implicit_neighbor_columns): type checking
+	bugfix.
+
+	* lily/span-arpeggio-engraver.cc (stop_translation_timestep):
+	typecheck bugfix. 
+
+	* lily/grob.cc (ly_get_grob_property): be anal about types.
+	(ly_set_grob_property): idem
+
+	* lily/figured-bass-engraver.cc (process_music): move molecule
+	building completely to Scheme
+
+	* lily/include/musical-request.hh (class Bass_figure_req): Add
+	class. 
+
+	* lily/parser.yy (bass_figure): add support for space figure.
+
+	* lily/molecule.cc (ly_molecule_combined_at_edge): be anal about types 
+
+	* lily/font-metric.cc (ly_text_dimension): Scheme function ly-text-dimension
+
+	* lily/molecule.cc (ly_fontify_atom): new function ly-fontify-atom
+	(ly_align_to_x): new function ly-align-to!
+
+	* lily/font-interface.cc (ly_font_interface_get_font): new Scheme
+	function ly-get-font
+
+	* mf/feta-nummer.mf: include normal-space dimension. 
+
+	* lily/collision.cc (check_meshing_chords): don't merge collisions
+	with whole notes.
+	
+	* lily/system-start-delimiter.cc (after_line_breaking): Bugfix:
+	glyph is string.
+
+2002-02-28  Mats Bengtsson  <matsb@matsb@s3.kth.se>
+
+	* scm/tex.scm, scm/ps.scm (or): Bugfix, ps output with Guile 3.4
+
+2002-02-28  Juergen Reuter  <reuter@ipd.uka.de>
+
+	* mf/parmesan-heads.mf: bugfix: mensural note heads  (WARNING:
+	font changed)
+
+	* scm/output-lib.scm: bugfix: resort to neo_mensural chars rather
+	than mensural chars
+
+	* mf/parmesan-scripts.mf, mf/parmesan-generic.mf,
+	scm/grob-description.scm: added mensural fermata symbol
+
 2002-02-27  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
 
 	* VERSION: 1.5.34 released.
@@ -440,6 +500,7 @@
 	Changed property:   localKeySignature.
 	Added properties:   extraNatural, autoAccidentals,
 	                    autoCautionaries.
+
 	(BUGFIX: broken-tie-support destroyed in 1.5.16)
 	
 	* ly/property-init.ly: added commands
diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely
index 208904fae8..100d39fc95 100644
--- a/Documentation/regression-test.tely
+++ b/Documentation/regression-test.tely
@@ -88,15 +88,17 @@ Accidentals are currently in a development stage.
 @section Chord names
 
 @lilypondfile[printfilename]{chord-names.ly}
+
 @lilypondfile[printfilename]{chord-changes.ly}
 
+@section Figured bass
 
+@lilypondfile[printfilename]{figured-bass.ly}
 
 @section Grace notes
 
 Grace note do weird things with timing. Fragile.
 
-
 @lilypondfile[printfilename]{grace.ly}
 
 @lilypondfile[printfilename]{grace-bar-line.ly}
@@ -108,6 +110,7 @@ Grace note do weird things with timing. Fragile.
 @lilypondfile[printfilename]{grace-nest4.ly}
 
 @lilypondfile[printfilename]{grace-nest5.ly}
+
 @lilypondfile[printfilename]{grace-nest1.ly}
 
 @lilypondfile[printfilename]{grace-start.ly}
@@ -125,8 +128,11 @@ Grace note do weird things with timing. Fragile.
 
 @lilypondfile[printfilename]{beam-position.ly}
 
+
 @lilypondfile[printfilename]{auto-beam-bar.ly}
 
+@lilypondfile[printfilename]{beam-over-barline.ly}
+
 @lilypondfile[printfilename]{beam-rest.ly}
 
 @lilypondfile[printfilename]{beam-length.ly}
@@ -139,6 +145,7 @@ Grace note do weird things with timing. Fragile.
 
 @lilypondfile[printfilename]{triplets.ly}
 
+@lilypondfile[printfilename]{beaming-ternary-metrum.ly}
 
 @section  Slurs 
 
diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely
index 133e45f318..c2786787ff 100644
--- a/Documentation/user/refman.itely
+++ b/Documentation/user/refman.itely
@@ -1366,9 +1366,11 @@ To save typing work, some shorthands are available:
 
 @cindex fingering
 
-Fingering instructions can also be entered in  this shorthand.
+Fingering instructions can also be entered in  this shorthand. For
+changes, some markup texts would be needed:
 @lilypond[verbatim, singleline, fragment]
       c'4-1 c'4-2 c'4-3 c'4-4
+      c^#'(finger "2-3")
 @end lilypond
 
 
@@ -2873,24 +2875,7 @@ block:
 
 @cindex Basso continuo
 
-Figured bass is printed by @internalsref{FiguredBass} context.  This
-context will print notes (relative to the central C) as figures.  To
-ease entering these notes, the special @code{\figures} mode is
-available which allows you to type numbers, like @code{<4 6+>}.
-
-@lilypond[verbatim,fragment]
-< \context FiguredBass \transpose c'' {
-   <e! g >
-   <f8 ais >
-   \figures {
-     r8
-     <1 3 5>4 <3- 5+ 6!> <5>
-   } 
- }
- \context Voice {
-   c g8 g f4 d c
-  } >
-@end lilypond
+TODO. see figured-bass.ly
 
 @c . {Tuning output}
 @node Tuning output
diff --git a/NEWS b/NEWS
index 6dad565384..ce25038d6f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,7 @@
 
 New features in 1.5
 
-* Many speedups
+* Many speedups, many slowdowns.
 
 * Figured bass support
 
@@ -10,3 +10,5 @@ New features in 1.5
 * Better spacing.
 
 * More ancient notation support.
+
+* Some entry optimizations
diff --git a/VERSION b/VERSION
index 01b2d92cf8..f36d3ce01b 100644
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=5
-PATCH_LEVEL=34
+PATCH_LEVEL=35
 MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
diff --git a/input/regression/beam-over-barline.ly b/input/regression/beam-over-barline.ly
new file mode 100644
index 0000000000..6f57cff901
--- /dev/null
+++ b/input/regression/beam-over-barline.ly
@@ -0,0 +1,6 @@
+\header {
+texidoc = "explicit beams may cross barlines. "
+}
+\score {
+\notes \context Voice { c2. [c8 c8 c8 c8] }
+}
diff --git a/input/regression/beaming-ternary-metrum.ly b/input/regression/beaming-ternary-metrum.ly
new file mode 100644
index 0000000000..a0fcb46bd2
--- /dev/null
+++ b/input/regression/beaming-ternary-metrum.ly
@@ -0,0 +1,10 @@
+\header {
+texidoc = "automatic beaming also works in ternary time sigs."
+}
+
+\score {
+   \notes \context Staff {
+\time 6/8
+[c8. c16 c16 c16] 
+}
+}
diff --git a/input/regression/figured-bass.ly b/input/regression/figured-bass.ly
new file mode 100644
index 0000000000..47893be4fc
--- /dev/null
+++ b/input/regression/figured-bass.ly
@@ -0,0 +1,25 @@
+\header {
+texidoc = "Test figured bass.
+
+Figured bass is created by the FiguredBass context which eats
+figured bass requests and  rest-requests.  You must enter these using
+the special @code{\figures @{ @}} mode, which allows you to type
+numbers, like @code{<4 6+>}.
+ 
+" }
+
+\score { \notes  <
+ \context FiguredBass {
+   \figures {
+	<_! 3+ 5- _ 7! 9 >4
+	< 4 6 >
+   }
+ }
+
+ \context Voice {
+   c 4
+   g8
+  }
+ 
+>
+ }
diff --git a/lily/bass-figure.cc b/lily/bass-figure.cc
new file mode 100644
index 0000000000..7a6d962d81
--- /dev/null
+++ b/lily/bass-figure.cc
@@ -0,0 +1,7 @@
+/*
+  bass-figure.cc 
+ */
+
+
+
+
diff --git a/lily/collision.cc b/lily/collision.cc
index 2dea673021..07b681ee2a 100644
--- a/lily/collision.cc
+++ b/lily/collision.cc
@@ -108,7 +108,13 @@ check_meshing_chords (Grob*me,
 
   merge_possible = merge_possible &&
     Rhythmic_head::balltype_i (nu_l) == Rhythmic_head::balltype_i (nd_l);
-    
+
+
+  /*
+    don't merge whole notes (or longer, like breve, longa, maxima) 
+   */
+  merge_possible = merge_possible && (Rhythmic_head::balltype_i (nu_l) > 0);
+
   if (!to_boolean (me->get_grob_property ("merge-differently-dotted")))
     merge_possible = merge_possible && Rhythmic_head::dot_count (nu_l) == Rhythmic_head::dot_count (nd_l);
   
@@ -171,6 +177,7 @@ check_meshing_chords (Grob*me,
     shift_amount *= 0.4;
   else if (distant_half_collide || close_half_collide || full_collide)
     shift_amount *= 0.5;
+  
   /*
     we're meshing.
   */
diff --git a/lily/command-request.cc b/lily/command-request.cc
index 62cbac4fa3..061063eacc 100644
--- a/lily/command-request.cc
+++ b/lily/command-request.cc
@@ -92,7 +92,7 @@ Mark_req::do_equal_b (Request const * r) const
 			       get_mus_property ("label")) == SCM_BOOL_T;
 }
 
-
+ADD_MUSIC(Bass_figure_req);
 ADD_MUSIC (Articulation_req);
 ADD_MUSIC (Break_req);
 ADD_MUSIC (Breathing_sign_req);
diff --git a/lily/engraver-group-engraver.cc b/lily/engraver-group-engraver.cc
index b30a854d16..03b268ea76 100644
--- a/lily/engraver-group-engraver.cc
+++ b/lily/engraver-group-engraver.cc
@@ -34,8 +34,36 @@ Engraver_group_engraver::create_grobs_in_simple_children ()
 }
 
 /*
-  TODO: use this mechanism for the current Engraver_group_engraver as well.
-  
+
+  '''Done: eliminating useless broadcast/acknowledge'''
+
+
+One cause for translation slowness: grob broadcasted/acknowledges
+(b/a): every grob is b/a'd to all peer-engravers and all
+parent-engravers. This means that lots of (often) useless b/a is done
+for large scores (the top-level engravers gets to know every detail of
+every voice, thread, etc. Measurements indicate this is 10% of the
+interpretation time:
+
+standchen
+
+old: (pre 1.5.13)  10.28
+new: 8.73
+speedup: 15 %
+
+Coriolan:
+
+new: 197.59
+old: 219.12 seconds
+speedup: 10%
+
+
+The cost of this B/A is # of useless engravers * cost of one ack,
+which is rather low, since cost of one ack is only an interface check.
+The cost of precomputing engraver lists has two elts: computing the
+list itself, GC for the structure, looking up the list during the
+acks.
+
  */
 SCM find_acknowledge_engravers (SCM gravlist, SCM meta);
 void
diff --git a/lily/figured-bass-engraver.cc b/lily/figured-bass-engraver.cc
index 9703975358..9e97d0e018 100644
--- a/lily/figured-bass-engraver.cc
+++ b/lily/figured-bass-engraver.cc
@@ -8,7 +8,7 @@ class Figured_bass_engraver : public Engraver
   
   TRANSLATOR_DECLARATIONS(Figured_bass_engraver);
 protected:
-  Link_array<Note_req> figures_;
+  Link_array<Bass_figure_req> figures_;
   Rest_req * rest_req_;
 
   Grob * figure_;
@@ -31,7 +31,7 @@ Figured_bass_engraver::stop_translation_timestep ()
   if (figure_)
     {
       typeset_grob (figure_);
-      figure_ =00;
+      figure_ = 0;
     }
 
   figures_.clear ();
@@ -41,9 +41,9 @@ Figured_bass_engraver::stop_translation_timestep ()
 bool
 Figured_bass_engraver::try_music (Music*m)
 {
-  if (Note_req* n = dynamic_cast<Note_req*> (m))
+  if (Bass_figure_req* bfr = dynamic_cast<Bass_figure_req*> (m))
     {
-      figures_.push (n);
+      figures_.push (bfr);
       return true;
     }
   else if (Rest_req * r = dynamic_cast<Rest_req*> (m))
@@ -66,36 +66,13 @@ Figured_bass_engraver::process_music ()
   else if (figures_.size ())
     {
       figure_ = new Item (get_property ("BassFigure"));
-      announce_grob(figure_, figures_[0]->self_scm()); // todo
-      SCM flist = SCM_EOL;
-      for (int i = 0; i < figures_.size (); i++)
-	{
-	  Note_req * n = figures_[i];
-	  Pitch *p = unsmob_pitch (n->get_mus_property ("pitch"));
-	  
-	  String fstr = to_str (p->steps ()+ 1);
-	  
-	  SCM one_fig = ly_str02scm(fstr.ch_C ());
-
-	  if (p->alteration_i_ || to_boolean (n->get_mus_property ("force-accidental") ))
-	    {
-	      SCM alter = scm_assoc (gh_int2scm (p->alteration_i_),
-				     figure_->get_grob_property ("accidental-alist"));
-	      if (gh_pair_p (alter))
-		{
-		  one_fig = scm_list_n (ly_symbol2scm ("columns"),
-				     one_fig,
-				     ly_cdr(alter),
-				     SCM_UNDEFINED);
-		}
-	    }
-	  
-	  flist = gh_cons (one_fig, flist);
-	}
+      SCM l = SCM_EOL;
 
-      flist = gh_cons (ly_symbol2scm ("lines"), flist);
-
-      figure_-> set_grob_property ("text", flist);
+      for (int i = 0; i <figures_.size (); i++)
+	l = gh_cons (figures_[i]->self_scm(), l);
+      figure_->set_grob_property ("causes", l);
+      
+      announce_grob(figure_, figures_[0]->self_scm()); // todo
     }
 }
 
diff --git a/lily/font-interface.cc b/lily/font-interface.cc
index d0e23e9bc0..c0f7757823 100644
--- a/lily/font-interface.cc
+++ b/lily/font-interface.cc
@@ -35,6 +35,9 @@ scaling)
 SCM
 Font_interface::font_alist_chain (Grob *me)
 {
+  /*
+    Ugh: why the defaults?
+   */
   SCM defaults = ly_cdr (scm_assoc (ly_symbol2scm ("font-defaults"),
 				    me->paper_l ()->style_sheet_));
 
@@ -76,6 +79,20 @@ ly_font_interface_get_default_font (SCM grob)
   return Font_interface::get_default_font (gr)->self_scm ();
 }
 
+SCM
+ly_font_interface_get_font (SCM grob, SCM alist)
+{
+  Grob * gr  = unsmob_grob (grob);
+  SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
+
+  Font_metric*fm=
+    Font_interface::get_font (gr, gh_cons (alist,
+					   Font_interface::font_alist_chain (gr)));
+
+  return fm->self_scm();
+}
+
+
 
 Font_metric *
 Font_interface::get_font (Grob *me, SCM chain)
@@ -153,6 +170,8 @@ init_syms ()
 
   scm_c_define_gsubr ("ly-get-default-font", 1 , 0, 0,
 		      (Scheme_function_unknown) ly_font_interface_get_default_font);
+  scm_c_define_gsubr ("ly-get-font", 2, 0, 0,
+		      (Scheme_function_unknown) ly_font_interface_get_font);
 }
 
 
diff --git a/lily/font-metric.cc b/lily/font-metric.cc
index 11f63489e8..577471baa3 100644
--- a/lily/font-metric.cc
+++ b/lily/font-metric.cc
@@ -148,11 +148,33 @@ ly_find_glyph_by_name (SCM font, SCM name)
 }
 
 
+SCM
+ly_text_dimension (SCM font, SCM text)
+{
+  Box b;
+  
+  if (!unsmob_metrics (font) || !gh_string_p(text))
+    {
+      warning ("ly-find-glyph-by-name: invalid argument.");
+      Molecule m;
+      return m.smobbed_copy ();
+    }
+  else
+    {
+      b = unsmob_metrics (font)->text_dimension (ly_scm2string (text));
+    }
+  
+  return gh_cons (ly_interval2scm (b[X_AXIS]), ly_interval2scm(b[Y_AXIS]));
+}
+
+
 static void
 font_metric_init ()
 {
    scm_c_define_gsubr ("ly-find-glyph-by-name", 2 , 0, 0,
 		       (Scheme_function_unknown) ly_find_glyph_by_name);
+   scm_c_define_gsubr ("ly-text-dimension", 2 , 0, 0,
+		       (Scheme_function_unknown) ly_text_dimension);
 }
 
 ADD_SCM_INIT_FUNC (font_metric_init, font_metric_init);
diff --git a/lily/grob.cc b/lily/grob.cc
index 4077188023..064b68faab 100644
--- a/lily/grob.cc
+++ b/lily/grob.cc
@@ -815,27 +815,13 @@ SCM
 ly_set_grob_property (SCM elt, SCM sym, SCM val)
 {
   Grob * sc = unsmob_grob (elt);
-
-  if (!gh_symbol_p (sym))
-    {
-      error ("Not a symbol");
-      ly_display_scm (sym);
-      return SCM_UNSPECIFIED;
-    }
+  SCM_ASSERT_TYPE(sc, elt, SCM_ARG1, __FUNCTION__, "grob");
+  SCM_ASSERT_TYPE(gh_symbol_p(sym), sym, SCM_ARG2, __FUNCTION__, "symbol");  
 
   if (!type_check_assignment (sym, val, ly_symbol2scm ("backend-type?")))
-    return SCM_UNSPECIFIED;
+    error ("typecheck failed");
       
-  if (sc)
-    {
-      sc->internal_set_grob_property (sym, val);
-    }
-  else
-    {
-      error ("Not a score element");
-      ly_display_scm (elt);
-    }
-
+  sc->internal_set_grob_property (sym, val);
   return SCM_UNSPECIFIED;
 }
 
@@ -844,17 +830,10 @@ SCM
 ly_get_grob_property (SCM elt, SCM sym)
 {
   Grob * sc = unsmob_grob (elt);
-  
-  if (sc)
-    {
-      return sc->internal_get_grob_property (sym);
-    }
-  else
-    {
-      error ("Not a score element");
-      ly_display_scm (elt);
-    }
-  return SCM_UNSPECIFIED;
+  SCM_ASSERT_TYPE(sc, elt, SCM_ARG1, __FUNCTION__, "grob");
+  SCM_ASSERT_TYPE(gh_symbol_p(sym), sym, SCM_ARG2, __FUNCTION__, "symbol");  
+
+  return sc->internal_get_grob_property (sym);
 }
 
 
diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh
index 69eda94276..f957616d8b 100644
--- a/lily/include/lily-guile.hh
+++ b/lily/include/lily-guile.hh
@@ -148,6 +148,7 @@ SCM ly_parse_scm (char const* s, int* n);
 SCM ly_quote_scm (SCM s);
 SCM ly_type (SCM);
 bool type_check_assignment (SCM val, SCM sym,  SCM type_symbol) ;
+String print_scm_val (SCM val);
 SCM ly_number2string (SCM s);
 
 SCM parse_symbol_list (char const *);
diff --git a/lily/include/lookup.hh b/lily/include/lookup.hh
index 9fa1ffce02..17b8a5e654 100644
--- a/lily/include/lookup.hh
+++ b/lily/include/lookup.hh
@@ -18,6 +18,7 @@
 
 struct Lookup
 {
+  static Molecule bracket (Axis a, Interval iv, Direction d, Real thick, Real protude);
   static Molecule accordion (SCM arg, Real interline_f, Font_metric*fm);
   static Molecule frame (Box b, Real thick);
   static Molecule slur (Bezier controls, Real cthick, Real thick) ;
diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh
index 17f5446ea2..4511e660a0 100644
--- a/lily/include/musical-request.hh
+++ b/lily/include/musical-request.hh
@@ -162,4 +162,10 @@ public:
   VIRTUAL_COPY_CONS (Music);
 };
 
+class Bass_figure_req:  public Rhythmic_req
+{
+public:
+  VIRTUAL_COPY_CONS(Music);
+};
+
 #endif // MUSICALREQUESTS_HH
diff --git a/lily/lexer.ll b/lily/lexer.ll
index fa5a4dad89..7bff8df6f4 100644
--- a/lily/lexer.ll
+++ b/lily/lexer.ll
@@ -269,6 +269,15 @@ HYPHEN		--
 	return SCM_T;
 }
 <figures>{
+	_	{
+		return FIGURE_SPACE;
+	}
+	\]	{
+		return FIGURE_BRACKET_CLOSE;
+	}
+	\[	{
+		return FIGURE_BRACKET_OPEN;
+	}
 	\>		{
 		return FIGURE_CLOSE;
 	}
diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc
index 12b925a567..cf15fbd962 100644
--- a/lily/lily-guile.cc
+++ b/lily/lily-guile.cc
@@ -607,6 +607,15 @@ SCM my_gh_symbol2scm (const char* x)
   return gh_symbol2scm ((char*)x);
 }
 
+String
+print_scm_val (SCM val)
+{
+  String realval = ly_scm2string (ly_write2scm (val));
+  if (realval.length_i () > 200)
+    realval = realval.left_str (100) + "\n :\n :\n" + realval.right_str (100);
+  
+  return realval;	 
+}
 
 bool
 type_check_assignment (SCM sym, SCM val,  SCM type_symbol) 
@@ -647,14 +656,10 @@ type_check_assignment (SCM sym, SCM val,  SCM type_symbol)
 	  SCM typefunc = scm_primitive_eval (ly_symbol2scm ("type-name"));
 	  SCM type_name = gh_call1 (typefunc, type_p);
 
-	  String realval = ly_scm2string (ly_write2scm (val));
-	  if (realval.length_i () > 200)
-	    realval = realval.left_str (100) + "\n :\n :\n" + realval.right_str (100);
-	    
-	  
+	 
 	  scm_puts (_f ("Type check for `%s' failed; value `%s' must be of type `%s'",
 			ly_symbol2string (sym).ch_C (),
-			realval.ch_C (),
+			print_scm_val (val),
 			ly_scm2string (type_name).ch_C ()).ch_C (),
 		    errport);
 	  scm_puts ("\n", errport);		      
diff --git a/lily/lookup.cc b/lily/lookup.cc
index 60cc0c6269..3415820205 100644
--- a/lily/lookup.cc
+++ b/lily/lookup.cc
@@ -46,7 +46,6 @@ Lookup::beam (Real slope, Real width, Real thick)
 }
 
 
-
 Molecule
 Lookup::dashed_slur (Bezier b, Real thick, Real dash)
 {
@@ -67,9 +66,6 @@ Lookup::dashed_slur (Bezier b, Real thick, Real dash)
   return   Molecule (box, at);
 }
 
-
-
-
 Molecule
 Lookup::blank (Box b) 
 {
@@ -90,6 +86,7 @@ Lookup::filledbox (Box b)
   return Molecule (b,at);
 }
 
+
 Molecule
 Lookup::frame (Box b, Real thick)
 {
@@ -107,7 +104,6 @@ Lookup::frame (Box b, Real thick)
 	  edges[o][DOWN] = b[o][DOWN] - thick/2;
 	  edges[o][UP] = b[o][UP] + thick/2;	  
 	  
-	  
 	  m.add_molecule (filledbox (edges));
 	}
       while (flip (&d) != LEFT);
@@ -164,6 +160,9 @@ Lookup::slur (Bezier curve, Real curvethick, Real linethick)
   return Molecule (b, at);
 }
 
+/*
+  TODO: junk me.
+ */
 Molecule
 Lookup::accordion (SCM s, Real staff_space, Font_metric *fm) 
 {
@@ -380,3 +379,49 @@ Lookup::repeat_slash (Real w, Real s, Real t)
 
   return Molecule (b, slashnodot); //  http://slashnodot.org
 }
+
+
+
+Molecule
+Lookup::bracket (Axis a, Interval iv, Direction d, Real thick, Real protude)
+{
+  Box b;
+  Axis other = Axis((a+1)%2);
+  b[a] = iv;
+  b[other] = Interval(-1, 1) * thick * 0.5;
+  
+  Molecule m =  filledbox (b);
+
+  b[a] = Interval (iv[UP] - thick, iv[UP]);
+  Interval oi = Interval (-thick/2, thick/2 + protude) ;
+  oi *=  d;
+  b[other] = oi;
+  m.add_molecule (filledbox (b));
+  b[a] = Interval (iv[DOWN], iv[DOWN]  +thick);
+  m.add_molecule (filledbox(b));
+
+  return m;
+}
+
+SCM
+ly_bracket (SCM a, SCM iv, SCM d, SCM t, SCM p)
+{
+  SCM_ASSERT_TYPE(ly_axis_p (a), a, SCM_ARG1, __FUNCTION__, "axis") ;
+  SCM_ASSERT_TYPE(ly_number_pair_p (iv), iv, SCM_ARG1, __FUNCTION__, "number pair") ;
+  SCM_ASSERT_TYPE(isdir_b (d), a, SCM_ARG1, __FUNCTION__, "direction") ;
+  SCM_ASSERT_TYPE(gh_number_p (t), a, SCM_ARG1, __FUNCTION__, "number") ;
+  SCM_ASSERT_TYPE(gh_number_p(p), a, SCM_ARG1, __FUNCTION__, "number") ;
+
+
+  return Lookup::bracket ((Axis)gh_scm2int (a), ly_scm2interval (iv),
+		  (Direction)gh_scm2int (d), gh_scm2double (t), gh_scm2double (p)).smobbed_copy ();
+}
+  
+static void
+lookup_init ()
+{
+  scm_c_define_gsubr ("ly-bracket", 5, 0, 0, (Scheme_function_unknown) ly_bracket);
+}
+
+ADD_SCM_INIT_FUNC (lookup,lookup_init);
+
diff --git a/lily/molecule.cc b/lily/molecule.cc
index 9630568288..6a7709a5bc 100644
--- a/lily/molecule.cc
+++ b/lily/molecule.cc
@@ -137,13 +137,13 @@ SCM
 Molecule::ly_set_molecule_extent_x (SCM mol, SCM axis, SCM np)
 {
   Molecule* m = unsmob_molecule (mol);
-  if (m && ly_axis_p (axis) && ly_number_pair_p (np))
-    {
-      Interval iv = ly_scm2interval (np);
-      m->dim_[Axis (gh_scm2int (axis))] = iv;
-    }
-  else
-    warning ("ly-set-molecule-extent!: invalid arguments");
+  SCM_ASSERT_TYPE (m, mol, SCM_ARG1, __FUNCTION__, "molecule");
+  SCM_ASSERT_TYPE (ly_axis_p(axis), axis, SCM_ARG2, __FUNCTION__, "axis");
+  SCM_ASSERT_TYPE (ly_number_pair_p (np), np, SCM_ARG3, __FUNCTION__, "number pair");
+
+  Interval iv = ly_scm2interval (np);
+  m->dim_[Axis (gh_scm2int (axis))] = iv;
+
   return SCM_UNDEFINED;
 }
 
@@ -164,24 +164,23 @@ Molecule::ly_get_molecule_extent (SCM mol, SCM axis)
 
 SCM
 Molecule::ly_molecule_combined_at_edge (SCM first, SCM axis, SCM direction,
-			   SCM second, SCM padding)
+					SCM second, SCM padding)
 
 {
   Molecule * m1 = unsmob_molecule (first);
   Molecule * m2 = unsmob_molecule (second);
   Molecule result;
-  
-  if (!m1 || !m2 || !isdir_b (direction) || !ly_axis_p (axis) || !gh_number_p (padding))
-    {
-      warning ("ly-combine-molecule-at-edge: invalid arguments");
-      Molecule r;
-      return  r.smobbed_copy ();
-    }
 
-  result = *m1;
 
-  result.add_at_edge (Axis (gh_scm2int (axis)), Direction (gh_scm2int (direction)),
-		      *m2, gh_scm2double (padding));
+  SCM_ASSERT_TYPE(ly_axis_p(axis), axis, SCM_ARG2, __FUNCTION__, "axis");
+  SCM_ASSERT_TYPE(isdir_b (direction), direction, SCM_ARG3, __FUNCTION__, "dir");
+  SCM_ASSERT_TYPE(gh_number_p(padding), padding, SCM_ARG4, __FUNCTION__, "number");
+
+  if (m1)
+    result = *m1;
+  if (m2)
+    result.add_at_edge (Axis (gh_scm2int (axis)), Direction (gh_scm2int (direction)),
+			*m2, gh_scm2double (padding));
 
   return result.smobbed_copy ();
 }
@@ -198,11 +197,43 @@ make_molecule (SCM expr, SCM xext, SCM yext)
   return m.smobbed_copy ();
 }
 
+SCM
+fontify_atom (Font_metric * met, SCM f)
+{
+  if (f == SCM_EOL)
+    return f;
+  else
+    return  scm_list_n (ly_symbol2scm ("fontify"),
+			ly_quote_scm (met->description_), f, SCM_UNDEFINED);
+}
+
+SCM
+ly_fontify_atom (SCM met, SCM f)
+{
+  SCM_ASSERT_TYPE(unsmob_metrics (met), met, SCM_ARG1, __FUNCTION__, "font metric");
+
+  return fontify_atom (unsmob_metrics (met), f);
+}
+
+SCM
+ly_align_to_x (SCM mol, SCM axis, SCM dir)
+{
+  SCM_ASSERT_TYPE(unsmob_molecule (mol), mol, SCM_ARG1, __FUNCTION__, "molecule");
+  SCM_ASSERT_TYPE(ly_axis_p(axis), axis, SCM_ARG2, __FUNCTION__, "axis");
+  SCM_ASSERT_TYPE(isdir_b (dir), dir, SCM_ARG3, __FUNCTION__, "dir");
+
+  unsmob_molecule (mol)->align_to ((Axis)gh_scm2int (axis), Direction (gh_scm2int (dir)));
+
+  return SCM_UNDEFINED;
+}
+
 
 static void
 molecule_init ()
 {
   scm_c_define_gsubr ("ly-make-molecule", 3, 0, 0, (Scheme_function_unknown) make_molecule);
+  scm_c_define_gsubr ("ly-fontify-atom", 2, 0, 0, (Scheme_function_unknown) ly_fontify_atom);
+  scm_c_define_gsubr ("ly-align-to!", 3, 0, 0, (Scheme_function_unknown) ly_align_to_x);    
   scm_c_define_gsubr ("ly-combine-molecule-at-edge", 5 , 0, 0, (Scheme_function_unknown) Molecule::ly_molecule_combined_at_edge);
   scm_c_define_gsubr ("ly-set-molecule-extent!", 3 , 0, 0, (Scheme_function_unknown) Molecule::ly_set_molecule_extent_x);
   scm_c_define_gsubr ("ly-get-molecule-extent", 2 , 0, 0, (Scheme_function_unknown) Molecule::ly_get_molecule_extent);
@@ -216,16 +247,6 @@ Molecule::empty_b () const
   return expr_ == SCM_EOL;
 }
 
-SCM
-fontify_atom (Font_metric * met, SCM f)
-{
-  if (f == SCM_EOL)
-    return f;
-  else
-    return  scm_list_n (ly_symbol2scm ("fontify"),
-		     ly_quote_scm (met->description_), f, SCM_UNDEFINED);
-}
-
 SCM
 Molecule::get_expr () const
 {
diff --git a/lily/music.cc b/lily/music.cc
index b00c8519d6..f2939fb4f5 100644
--- a/lily/music.cc
+++ b/lily/music.cc
@@ -174,7 +174,7 @@ Music::internal_set_mus_property (SCM s, SCM v)
 {
 #ifndef NDEBUG
   if (internal_type_checking_global_b)
-    assert (type_check_assignment (s, v, ly_symbol2scm ("backend-type?")));
+    assert (type_check_assignment (s, v, ly_symbol2scm ("music-type?")));
 #endif
   
 
diff --git a/lily/parser.yy b/lily/parser.yy
index 88e09abb57..c7a905166c 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -195,6 +195,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %token DURATION
 %token EXTENDER
 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
+%token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
 %token GLISSANDO
 %token GRACE 
 %token HEADER
@@ -244,11 +245,13 @@ yylex (YYSTYPE *s,  void * v_l)
 /* escaped */
 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE E_TILDE
 %token E_BACKSLASH
-%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET 
+%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET
+%token FIGURE_SPACE
+
 
 %type <i>	exclamations questions dots optional_rest
 %type <i>  	bass_number bass_mod
-%type <scm> 	bass_figure figure_list figure_spec
+%type <scm> 	br_bass_figure bass_figure figure_list figure_spec
 %token <i>	DIGIT
 %token <scm>	NOTENAME_PITCH
 %token <scm>	TONICNAME_PITCH
@@ -1713,31 +1716,49 @@ bass_mod:
 	;
 
 bass_figure:
-	bass_number  {
-		Pitch p ;
-		p .notename_i_ = $1 - 1;
-		p.normalise();
-		
-		Note_req * nr = new Note_req;
-		$$ = nr->self_scm ();
-		nr->set_mus_property ("pitch", p.smobbed_copy ());
+	FIGURE_SPACE {
+		Bass_figure_req *bfr = new Bass_figure_req;
+		$$ = bfr->self_scm();
+		scm_gc_unprotect_object ($$);
+	}
+	| bass_number  {
+		Bass_figure_req *bfr = new Bass_figure_req;
+		$$ = bfr->self_scm();
+
+		bfr->set_mus_property ("figure", gh_int2scm ($1));
+
 		scm_gc_unprotect_object ($$);
 	}
 	| bass_figure bass_mod {
-		if ($2) { 
-			SCM sp = unsmob_music ($1)->get_mus_property ("pitch");
-			unsmob_pitch (sp)->alteration_i_ += $2;
+		Music *m = unsmob_music ($1);
+		if ($2) {
+			SCM salter =m->get_mus_property ("alteration");
+			int alter = gh_number_p( salter) ? gh_scm2int (salter) : 0;
+			m->set_mus_property ("alteration",
+				gh_int2scm (alter + $2));
 		} else {
-			unsmob_music ($1)->set_mus_property ("force-accidental", SCM_BOOL_T);
+			m->set_mus_property ("alteration", gh_int2scm (0));
 		}
 	}
 	;
 
+br_bass_figure:
+	'[' bass_figure {
+		unsmob_music ($2)->set_mus_property ("bracket-start", SCM_BOOL_T);
+	}
+	| bass_figure	{
+
+	}
+	| br_bass_figure ']' {
+		unsmob_music ($1)->set_mus_property ("bracket-stop", SCM_BOOL_T);
+	}
+	;
+
 figure_list:
 	/**/		{
 		$$ = SCM_EOL;
 	}
-	| figure_list bass_figure {
+	| figure_list br_bass_figure {
 		$$ = gh_cons ($2, $1); 
 	}
 	;
diff --git a/lily/scm-option.cc b/lily/scm-option.cc
index 2eac1482ac..e472f2878e 100644
--- a/lily/scm-option.cc
+++ b/lily/scm-option.cc
@@ -11,7 +11,7 @@
 #include "string.hh"
 #include "lily-guile.hh"
 #include "scm-option.hh"
-
+#include "warn.hh"
 
 /*
   This interface to option setting is meant for setting options are
@@ -74,7 +74,7 @@ possible options for SYMBOL are :
 ")<<endl;
       
       cout << "  help (any-symbol)"<<endl; 
-      cout << "  internal-type-checks #t"<<endl; 
+      cout << "  internal-type-checking (boolean)"<<endl; 
       cout << "  midi-debug (boolean)"<<endl; 
       cout << "  testing-level (int)"<<endl; 
 
@@ -88,7 +88,7 @@ possible options for SYMBOL are :
     {
      testing_level_global = gh_scm2int (val); 
     }
-  else if (var == ly_symbol2scm ("internal-type-checks"))
+  else if (var == ly_symbol2scm ("internal-type-checking"))
     {
      internal_type_checking_global_b = to_boolean (val); 
     }
@@ -105,8 +105,12 @@ possible options for SYMBOL are :
       */
 
       ;
-      
     }
+  else
+    {
+      warning (_("Unknown internal option!"));
+    }
+  
 
   return SCM_UNSPECIFIED;
 }
diff --git a/lily/span-arpeggio-engraver.cc b/lily/span-arpeggio-engraver.cc
index 0753b2c245..4fd4f1a68e 100644
--- a/lily/span-arpeggio-engraver.cc
+++ b/lily/span-arpeggio-engraver.cc
@@ -91,7 +91,7 @@ Span_arpeggio_engraver::stop_translation_timestep ()
 	    we can't kill the children, since we don't want to the
 	    previous note to bump into the span arpeggio; so we make
 	    it transparent.  */
-	  arpeggios_[i]->set_grob_property ("molecule-callback", SCM_BOOL_T);
+	  arpeggios_[i]->set_grob_property ("molecule-callback", SCM_EOL);
 	}
       
       typeset_grob (span_arpeggio_);
diff --git a/lily/stem-engraver.cc b/lily/stem-engraver.cc
index cdf1a6b5d4..a23d1430a8 100644
--- a/lily/stem-engraver.cc
+++ b/lily/stem-engraver.cc
@@ -137,13 +137,13 @@ Stem_engraver::stop_translation_timestep ()
       if (gh_number_p (prop))
 	{
 	  Stem::set_beaming (stem_p_,gh_scm2int (prop),LEFT);
-	  daddy_trans_l_->set_property ("stemLeftBeamCount", SCM_UNDEFINED);
+	  daddy_trans_l_->unset_property (ly_symbol2scm ("stemLeftBeamCount"));
 	}
       prop = get_property ("stemRightBeamCount");
       if (gh_number_p (prop))
 	{
 	  Stem::set_beaming (stem_p_,gh_scm2int (prop), RIGHT);
-	  daddy_trans_l_->set_property ("stemRightBeamCount", SCM_UNDEFINED);
+	  daddy_trans_l_->unset_property (ly_symbol2scm ("stemRightBeamCount"));
 	}
 
       
diff --git a/lily/system-start-delimiter.cc b/lily/system-start-delimiter.cc
index b526caebb8..6d3846cd03 100644
--- a/lily/system-start-delimiter.cc
+++ b/lily/system-start-delimiter.cc
@@ -85,7 +85,8 @@ System_start_delimiter::after_line_breaking (SCM smob)
   Grob * me = unsmob_grob (smob);
   SCM   gl = me->get_grob_property ("glyph");
 
-  if (scm_ilength (me->get_grob_property ("elements")) <=  1 && gh_equal_p (gl,ly_str02scm ("bar-line")))
+  if (scm_ilength (me->get_grob_property ("elements")) <=  1
+      && gh_equal_p (gl,ly_str02scm ("bar-line")))
     {
       me->suicide ();
     }
@@ -101,9 +102,9 @@ System_start_delimiter::brew_molecule (SCM smob)
   Grob * me = unsmob_grob (smob);
 
   SCM s = me->get_grob_property ("glyph");
-  if (!gh_symbol_p (s))
+  if (!gh_string_p (s))
     return SCM_EOL;
-  
+  SCM gsym = scm_string_to_symbol (s) ;
   SCM c = me->get_grob_property ("collapse-height");
   
   Real staff_space = Staff_symbol_referencer::staff_space (me);
@@ -119,11 +120,12 @@ System_start_delimiter::brew_molecule (SCM smob)
     }
 
   Molecule m;
-  if (s == ly_symbol2scm ("bracket"))
+
+  if (gsym== ly_symbol2scm ("bracket"))
     m = staff_bracket (me,l);
-  else if (s == ly_symbol2scm ("brace"))
+  else if (gsym == ly_symbol2scm ("brace"))
     m =  staff_brace (me,l);
-  else if (s == ly_symbol2scm ("bar-line"))
+  else if (gsym == ly_symbol2scm ("bar-line"))
     m = simple_bar (me,l);
   
   m.translate_axis (ext.center (), Y_AXIS);
diff --git a/lily/third-try.cc b/lily/third-try.cc
index 2690c877c7..c91e3fd697 100644
--- a/lily/third-try.cc
+++ b/lily/third-try.cc
@@ -287,16 +287,20 @@ Third_spacing_spanner::set_implicit_neighbor_columns (Link_array<Grob> cols)
 	continue;
 
       // it->breakable || it->musical
+
+      /*
+	sloppy with typnig left/right-neighbors should take list, but paper-column found instead.
+       */
       SCM ln = cols[i] ->get_grob_property ("left-neighbors");
       if (!gh_pair_p (ln) && i ) 
 	{
-	  cols[i]->set_grob_property ("left-neighbors", cols[i-1]->self_scm());
+	  cols[i]->set_grob_property ("left-neighbors", gh_cons (cols[i-1]->self_scm(), SCM_EOL));
 	}
 
       SCM rn = cols[i] ->get_grob_property ("right-neighbors");
       if (!gh_pair_p (rn) && i < cols.size () - 1) 
 	{
-	  cols[i]->set_grob_property ("right-neighbors", cols[i + 1]->self_scm());
+	  cols[i]->set_grob_property ("right-neighbors", gh_cons (cols[i + 1]->self_scm(), SCM_EOL));
 	}
     }
 }
diff --git a/lily/translator-group.cc b/lily/translator-group.cc
index 48384af09f..fe46960c4e 100644
--- a/lily/translator-group.cc
+++ b/lily/translator-group.cc
@@ -306,7 +306,7 @@ Translator_group::internal_set_property (SCM sym, SCM val)
 {
 #ifndef NDEBUG
   if (internal_type_checking_global_b)
-    assert (type_check_assignment (sym, val, ly_symbol2scm ("backend-type?")));
+    assert (type_check_assignment (sym, val, ly_symbol2scm ("translation-type?")));
 #endif
   
   properties_dict ()->set (sym, val);
diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm
index 06c7e0a86d..fbbe7c17dc 100644
--- a/make/out/lilypond.lsm
+++ b/make/out/lilypond.lsm
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.5.34
-Entered-date: 27FEB02
+Version: 1.5.35
+Entered-date: 28FEB02
 Description: @BLURB@
 Keywords: music notation typesetting midi fonts engraving
 Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
 	janneke@gnu.org (Jan Nieuwenhuizen)
 Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
 Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
-	1000k lilypond-1.5.34.tar.gz 
+	1000k lilypond-1.5.35.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-	1000k lilypond-1.5.34.tar.gz 
+	1000k lilypond-1.5.35.tar.gz 
 Copying-policy: GPL
 End
diff --git a/make/out/lilypond.mandrake.spec b/make/out/lilypond.mandrake.spec
index d254955eb1..10c3901eb9 100644
--- a/make/out/lilypond.mandrake.spec
+++ b/make/out/lilypond.mandrake.spec
@@ -1,5 +1,5 @@
 %define name lilypond
-%define version 1.5.34
+%define version 1.5.35
 %define release 1mdk
 
 Name: %{name}
diff --git a/make/out/lilypond.redhat.spec b/make/out/lilypond.redhat.spec
index 0d3f3fabb7..fa24695e85 100644
--- a/make/out/lilypond.redhat.spec
+++ b/make/out/lilypond.redhat.spec
@@ -3,11 +3,11 @@
 %define info yes
 
 Name: lilypond
-Version: 1.5.34
+Version: 1.5.35
 Release: 1
 License: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.34.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.35.tar.gz
 Summary: Create and print music notation 
 URL: http://www.lilypond.org/
 BuildRoot: /tmp/lilypond-install
diff --git a/make/out/lilypond.suse.spec b/make/out/lilypond.suse.spec
index 4a388e55a3..f1c0e7425d 100644
--- a/make/out/lilypond.suse.spec
+++ b/make/out/lilypond.suse.spec
@@ -14,11 +14,11 @@
 
 Distribution: SuSE Linux 7.0 (i386)
 Name: lilypond
-Version: 1.5.34
+Version: 1.5.35
 Release: 2
 Copyright:    GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.34.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.35.tar.gz
 # music notation software for.. ?
 Summary: A program for printing sheet music.
 URL: http://www.lilypond.org/
diff --git a/mf/feta-nummer-code.mf b/mf/feta-nummer-code.mf
index eb5581eec2..fdfb569fb0 100644
--- a/mf/feta-nummer-code.mf
+++ b/mf/feta-nummer-code.mf
@@ -86,6 +86,10 @@ save dot_diam;
 dot_diam# = 7/8flare#;
 define_pixels(dot_diam);
 
+code := 32;
+fet_beginchar("Space", "space", "space")
+	set_char_box(0, space#,  0,height#);
+fet_endchar;
 
 code := 43;  % , = 44 
 
diff --git a/mf/feta-nummer.mf b/mf/feta-nummer.mf
index 898364cd23..5e9569779d 100644
--- a/mf/feta-nummer.mf
+++ b/mf/feta-nummer.mf
@@ -7,14 +7,19 @@ input feta-autometric;
 input feta-macros;
 input feta-params;
 
+
+
+
 %blot_diameter# = .4pt#;
 
 fet_beginfont("feta-nummer", design_size);
 mode_setup;
 
 height#:=designsize;
+space# := design_size/2;
 
 font_x_height height#;
+font_normal_space space#;
 
 save b,h; 4h+b=1.15; 10h+b=1;
 fatten:=designsize*h+b;
diff --git a/mf/feta-nummer12.mf b/mf/feta-nummer12.mf
new file mode 100644
index 0000000000..c3e868d31e
--- /dev/null
+++ b/mf/feta-nummer12.mf
@@ -0,0 +1,2 @@
+design_size := 12;
+input feta-nummer;
diff --git a/mf/parmesan-generic.mf b/mf/parmesan-generic.mf
index 94a5c52f26..53ce2688d1 100644
--- a/mf/parmesan-generic.mf
+++ b/mf/parmesan-generic.mf
@@ -1,11 +1,10 @@
-% 
-% feta-generic.mf --  implement generic stuff: include lots of files, but don't
-%  set dims.
+% -*-Fundamental-*-
+% parmesan-generic.mf --  implement generic stuff: include lots of files,
+% but don't set dims.
 %
-% source file of the Feta (defintively not an abbreviation for Font-En-Tja)
-% music font
+% source file of LilyPond's pretty-but-neat music font
 % 
-% (c) 1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+% (c) 2002 Juergen Reuter <reuter@ipd.uka.de>
 % 
 
 
@@ -32,6 +31,7 @@ if test = 0:
 	input parmesan-accidentals;
 	input parmesan-flags;
 	input parmesan-timesig;
+	input parmesan-scripts;
 
 else:
 
diff --git a/mf/parmesan-heads.mf b/mf/parmesan-heads.mf
index 688de02bf1..33aeea3091 100644
--- a/mf/parmesan-heads.mf
+++ b/mf/parmesan-heads.mf
@@ -70,7 +70,7 @@ enddef;
 % Some sources (eg Musix/OpusTeX think that the appendage should be on
 % the left, some say right. Right wins democratically.
 %
-def draw_longa (expr wid) =
+def draw_neo_longa (expr wid) =
 	draw_brevis(wid);
 	save theta;
 
@@ -91,15 +91,15 @@ enddef;
 %
 % (ze is wel breed)
 % 
-fet_beginchar("Maxima notehead", "-3mensural", "mensuralmaximahead");
-	draw_longa (1.3 brevis_wid#)
+fet_beginchar("Maxima notehead", "-3neo_mensural", "mensuralmaximahead");
+	draw_neo_longa (1.3 brevis_wid#)
 fet_endchar;
 
-fet_beginchar("Longa notehead", "-2mensural", "mensurallongahead");
-	draw_longa (brevis_wid#)
+fet_beginchar("Longa notehead", "-2neo_mensural", "mensurallongahead");
+	draw_neo_longa (brevis_wid#)
 fet_endchar;
 
-fet_beginchar("Brevis notehead", "-1mensural", "mensuralbrevishead")
+fet_beginchar("Brevis notehead", "-1neo_mensural", "mensuralbrevishead")
 	draw_brevis(brevis_wid#);
 fet_endchar;
 
@@ -141,19 +141,44 @@ def draw_neo_mensural_open_head (expr wid)=
 	unfill z5 -- z6 -- z7 -- z8 --cycle;
 enddef;
 
-fet_beginchar("Neo-mensural open head","0neo_mensural","neomensuralminimhead")
+fet_beginchar("Neo-mensural open head","0neo_mensural","neomensuralsemibrevishead")
       draw_neo_mensural_open_head (staff_space#);
 fet_endchar;
 
-fet_beginchar("Neo-mensural open head","1neo_mensural","neomensuralsemiminimhead")
+fet_beginchar("Neo-mensural open head","1neo_mensural","neomensuralminimahead")
       draw_neo_mensural_open_head (staff_space#);
 fet_endchar;
 
-fet_beginchar("Neo-mensural black head","2neo_mensural","neofusahead")
+fet_beginchar("Neo-mensural black head","2neo_mensural","neomensuralsemiminimahead")
       draw_neo_mensural_black_head (staff_space#);
 fet_endchar;
 
 
+brevis_wid# := 1 staff_space#;
+
+def draw_longa (expr wid) =
+	draw_brevis(wid);
+	save theta;
+
+	x6 = x7 = head_width - stem_width/2;
+	y6 = y5;
+	y7 = y5 - 2.25staff_space;
+	pickup pencircle scaled stem_width;
+	draw z6 .. z7;
+enddef;
+
+fet_beginchar("Maxima notehead", "-3mensural", "mensuralmaximahead");
+	draw_longa (2.0 brevis_wid#)
+fet_endchar;
+
+fet_beginchar("Longa notehead", "-2mensural", "mensurallongahead");
+	draw_longa (brevis_wid#)
+fet_endchar;
+
+fet_beginchar("Brevis notehead", "-1mensural", "mensuralbrevishead")
+	draw_brevis(brevis_wid#);
+fet_endchar;
+
 def draw_mensural_head (expr wid, open) =
       save head_width;
       head_width# = wid;
@@ -188,15 +213,15 @@ def draw_mensural_head (expr wid, open) =
 enddef;
 
 
-fet_beginchar("Mensural open head","0mensural","mensuralminimhead")
+fet_beginchar("Mensural open head","0mensural","mensuralsemibrevishead")
 	draw_mensural_head (staff_space#, true);
 fet_endchar;
 
-fet_beginchar("Mensural open head","1mensural","mensuralsemiminimhead")
+fet_beginchar("Mensural open head","1mensural","mensuralminimahead")
 	draw_mensural_head (staff_space#, true);
 fet_endchar;
 
-fet_beginchar("Mensural black head","2mensural","fusahead")
+fet_beginchar("Mensural black head","2mensural","mensuralsemiminimahead")
 	draw_mensural_head (staff_space#, false);
 fet_endchar;
 
diff --git a/mf/parmesan-scripts.mf b/mf/parmesan-scripts.mf
new file mode 100644
index 0000000000..ded015ce3e
--- /dev/null
+++ b/mf/parmesan-scripts.mf
@@ -0,0 +1,46 @@
+% -*-Fundamental-*-
+% parmesan-scripts.mf -- implement ancient script symbols
+% 
+% source file of LilyPond's pretty-but-neat music font
+% 
+% (c) 2002 Juergen Reuter <reuter@ipd.uka.de>
+% 
+
+fet_begingroup ("scripts")
+
+def draw_fermata =
+	save za, zb, zc, zd, ze, zf, zg, zh;
+	pair za, zb, zc, zd, ze, zf, zg, zh;
+
+	set_char_box(staff_space#/2, staff_space#/2,
+		     5/2*stafflinethickness#, 2staff_space#);
+
+	pickup pencircle
+		xscaled 1.0 stafflinethickness
+		yscaled 5.0 stafflinethickness
+		rotated -35;
+	za = (+0.50staff_space, +2.00staff_space);
+	zb = (+0.00staff_space, +2.00staff_space);
+	zc = (-0.50staff_space, +1.50staff_space);
+	zd = (-0.25staff_space, +1.00staff_space);
+	ze = (+0.10staff_space, +0.80staff_space);
+	zf = (+0.00staff_space, +0.00staff_space);
+	draw za{-1,+1} .. zb .. zc .. zd .. ze .. zf;
+
+	pickup pencircle scaled 3.0 stafflinethickness;
+	zg = (-0.5staff_space, +0.0staff_space);
+	zh = (+0.5staff_space, +0.0staff_space);
+	drawdot zg;
+	drawdot zh;
+enddef;
+
+fet_beginchar("fermata up", "ufermata", "ufermata")
+	draw_fermata;	
+fet_endchar;
+
+fet_beginchar("fermata down", "dfermata", "dfermata")
+	draw_fermata;
+	y_mirror_char;
+fet_endchar;
+
+fet_endgroup ("scripts")
diff --git a/scm/bass-figure.scm b/scm/bass-figure.scm
new file mode 100644
index 0000000000..409d582245
--- /dev/null
+++ b/scm/bass-figure.scm
@@ -0,0 +1,64 @@
+;;;; figured bass support ...
+
+;;;; todo: make interfaces as 1st level objects in LilyPond.
+
+
+(define (fontify-text font-metric text)
+  "Set TEXT with font FONT-METRIC, returning a molecule."
+  (let* ((b  (ly-text-dimension font-metric text)))
+    (ly-make-molecule
+     (ly-fontify-atom font-metric `(text ,text)) (car b) (cdr b))
+    ))
+
+(define (brew-one-figure grob fig-music)
+  "Brew a single column for a music figure"
+  (let* (
+	 (mf (ly-get-font grob '( (font-family .  music)  )))
+	 (nf (ly-get-font grob '( (font-family .  number)  )))
+	 (mol (ly-make-molecule  '() '(0 . 0) '(0 . 1.0)))
+	 (fig  (ly-get-mus-property fig-music 'figure))
+	 (acc  (ly-get-mus-property fig-music 'alteration))
+	 )
+    
+    (if (number? fig)
+	(begin
+	  (set! mol   (fontify-text nf (number->string fig)))
+	  (ly-align-to! mol Y CENTER)
+	))
+    
+    (if (number? acc)
+	(set! mol
+	      (ly-combine-molecule-at-edge
+	       mol 0 1 (ly-find-glyph-by-name mf (string-append "accidentals-" (number->string acc)))
+	       0.2))
+	)
+    (if (molecule? mol)
+	(ly-align-to! mol X CENTER)
+	)
+    mol))
+
+
+(define (stack-molecules axis dir padding mols)
+  "Stack molecules MOLS in direction AXIS,DIR, using PADDING."
+  (if (null? mols)
+      '()
+      (if (pair? mols)
+	  (ly-combine-molecule-at-edge (car mols) axis dir 
+				       (stack-molecules axis dir padding (cdr mols))
+				       padding
+				       )
+	  )
+  ))
+
+(define (brew-bass-figure grob)
+  "Make a molecule for a Figured Bass grob"
+  (let* (
+	 (figs (ly-get-grob-property grob 'causes ))
+	 (fig-mols (map (lambda (x) (brew-one-figure grob x)) figs))
+	 (fig-mol (stack-molecules 1 -1 0.2 fig-mols))
+	 )
+
+    (ly-align-to! fig-mol Y DOWN)
+    fig-mol
+  ))
+
diff --git a/scm/grob-description.scm b/scm/grob-description.scm
index 02bfd0d36d..3ea708e2f7 100644
--- a/scm/grob-description.scm
+++ b/scm/grob-description.scm
@@ -8,14 +8,6 @@
 ; distances are given in stafflinethickness (thicknesses) and
 ; staffspace (distances)
 
-(define default-alteration-alist
-  '(
-    (0 . ((raise . 0.5) (music "accidentals-0")))
-    (-1 . ((raise . 0.5) (music "accidentals--1")))
-    (-2 . ((raise . 0.5) (music "accidentals--2")))
-    (1 . ((raise . 0.5) (music  "accidentals-1")))
-    (2 . ((raise . 0.5) (music "accidentals-2")))
-    ))
 
 
 ;;; WARNING: the meta field should be the last one.
@@ -80,10 +72,9 @@
 	))
 
 	(BassFigure . (
-		       (molecule-callback . ,Text_item::brew_molecule)
+		       (molecule-callback . ,brew-bass-figure)
 		       (Y-offset-callbacks . (,Side_position_interface::aligned_on_self))
 		       (direction . 0)
-		       (accidental-alist . ,default-alteration-alist)
 		       (font-family . number)
 		       (font-relative-size . -1)
 		       (meta . ,(grob-description text-interface font-interface ))
@@ -505,6 +496,7 @@
 		(padding . 0.29) 
 		(X-offset-callbacks . (,Side_position_interface::centered_on_parent))
 		(before-line-breaking-callback . ,Script::before_line_breaking)
+		(font-family . music)
 		(meta . ,(grob-description script-interface side-position-interface font-interface))
 	))
 	
diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm
index b64817cf61..280fba7f67 100644
--- a/scm/grob-property-description.scm
+++ b/scm/grob-property-description.scm
@@ -432,3 +432,7 @@ function of type (beam multiplicity dy staff-line-thickness) -> real.  Default v
 (grob-property-description 'script-molecule pair? "index code for script.")
 
 (grob-property-description 'accidentals-grob ly-grob? "accidentals for this note.")
+
+(grob-property-description 'causes list? "list of cause objects.")
+(grob-property-description 'tremolo-flags number? "")
+(grob-property-description 'chord-tremolo boolean? "if set, this beam is a tremolo. TODO: use interface for this!")
diff --git a/scm/lily.scm b/scm/lily.scm
index a336564877..ba77f59747 100644
--- a/scm/lily.scm
+++ b/scm/lily.scm
@@ -147,6 +147,14 @@
 	    ))
 
 
+(define X 0)
+(define Y 1)
+(define LEFT -1)
+(define RIGHT 1)
+(define UP 1)
+(define DOWN -1)
+(define CENTER 0)
+
 (if (not standalone)
     (map ly-load
 					; load-from-path
@@ -154,6 +162,7 @@
 	   "pdf.scm"
 	   "pdftex.scm"
       	   "c++.scm"
+	   "bass-figure.scm"
 	   "grob-property-description.scm"
 	   "context-description.scm"
 	   "interface-description.scm"
diff --git a/scm/music-property-description.scm b/scm/music-property-description.scm
index 50fc4ad633..93933e1aff 100644
--- a/scm/music-property-description.scm
+++ b/scm/music-property-description.scm
@@ -60,9 +60,16 @@ TODO: consider making type into symbol ")
 (music-property-description 'repeat-count  integer? "do a @code{\repeat} how ofen?")
 (music-property-description 'span-direction dir? "Does this start or stop a spanner?")
 (music-property-description 'symbol symbol? "Grob name to perform an override/revert on.")
-(music-property-description 'text string? "markup expression to be printed")
+(music-property-description 'text markup? "markup expression to be printed")
 ;; markup?
 (music-property-description 'tremolo-type integer? "")
 (music-property-description 'value scheme? "Assignment value for a
 translation property")
 (music-property-description 'what string? "What to change for auto-change. FIXME, naming")
+
+(music-property-description 'figure number? "number for figured bass")
+(music-property-description 'alteration number? "alteration for figured bass")
+(music-property-description 'bracket-start boolean? "start a bracket
+here. TODO: use span requests?")
+(music-property-description 'bracket-stop boolean? "stop a bracket here.")
+
diff --git a/scm/output-lib.scm b/scm/output-lib.scm
index fb053465de..254732788f 100644
--- a/scm/output-lib.scm
+++ b/scm/output-lib.scm
@@ -64,11 +64,12 @@
 (define (find-notehead-symbol duration style)
   (case style
    ((xcircle) "2xcircle")
-   ((harmonic) "0mensural")
+   ((harmonic) "0neo_mensural")
    ((baroque) 
     (string-append (number->string duration)
-		   (if (< duration 0) "mensural" "")))
+		   (if (< duration 0) "neo_mensural" "")))
    ((mensural) (string-append (number->string duration) (symbol->string style)))
+   ((neo_mensural) (string-append (number->string duration) (symbol->string style)))
    ((default) (number->string duration))
    (else
     (string-append (number->string (max 0 duration)) (symbol->string style)))))
diff --git a/scm/tex.scm b/scm/tex.scm
index 123f7dc448..4f1466880c 100644
--- a/scm/tex.scm
+++ b/scm/tex.scm
@@ -130,7 +130,7 @@
     (define (embedded-ps expr)
       (let ((ps-string
 	     (with-output-to-string
-	       (lambda () (ps-output-expression expr)))))
+	       (lambda () (ps-output-expression expr (current-output-port))))))
 	(string-append "\\embeddedps{" ps-string "}")))
     (define (embedded-ps expr)
       (let
-- 
2.39.5