From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Thu, 22 Jan 2004 11:50:25 +0000 (+0000)
Subject: * scm/music-functions.scm (determine-split-list): bugfixes.
X-Git-Tag: release/2.1.23~183
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=3a64c1f4b7a0e880244a7369fa83d9c92ae8a184;p=lilypond.git

* scm/music-functions.scm (determine-split-list): bugfixes.

* scm/lily.scm (uniq-list): new implementation, O(1) stack.

* input/test/scales-greek.ly: use C as base, results in different
alterations at the clef.

* input/regression/pedal-ped.ly: new file.

* input/regression/pedal-bracket.ly: new file.

* lily/piano-pedal-bracket.cc (brew_molecule): new function;
replace after_line_breaking()

* lily/line-interface.cc (line): read thickness.
(line): dash-fraction = 0 always for dotted-line style.

* input/test/staff-lines.ly (lower): bugfix.

* scm/lily.scm: remove bla.scm load.
---

diff --git a/ChangeLog b/ChangeLog
index 2fec95871c..f9eb58c27a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2004-01-22  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+	* scm/music-functions.scm (determine-split-list): bugfixes.
+
+	* scm/lily.scm (uniq-list): new implementation, O(1) stack.
+
+	* input/test/scales-greek.ly: use C as base, results in different
+	alterations at the clef.
+
+	* input/regression/pedal-ped.ly: new file.
+
+	* input/regression/pedal-bracket.ly: new file.
+
+	* lily/piano-pedal-bracket.cc (brew_molecule): new function;
+	replace after_line_breaking()
+
+	* lily/line-interface.cc (line): read thickness.
+	(line): dash-fraction = 0 always for dotted-line style.
+
+	* input/test/staff-lines.ly (lower): bugfix.
+
 	* ly/engraver-init.ly (AncientRemoveEmptyStaffContext): move
 	\accepts Devnull into Score.
 
diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely
index 28c3d46a26..2dafbd0c0f 100644
--- a/Documentation/user/refman.itely
+++ b/Documentation/user/refman.itely
@@ -3203,7 +3203,8 @@ Pedals can also be indicated by a sequence of brackets, by setting the
 @end lilypond
 
 A third style of pedal notation is a mixture of text and brackets,
-obtained by setting @code{pedal-type} to @code{mixed}:
+obtained by setting the @code{pedalSustainStyle} style property to
+@code{mixed}:
 
 @lilypond[fragment,verbatim]
  \property Staff.pedalSustainStyle = #'mixed
@@ -3213,8 +3214,8 @@ c'4\sustainUp\sustainDown
 @end lilypond
 
 The default `*Ped' style for sustain and damper pedals corresponds to
-@code{\pedal-type = #'text}. However, @code{mixed} is the default style
-for a sostenuto pedal:
+style @code{#'text}. The sostenuto pedal uses @code{mixed} style by
+default.
 
 @lilypond[fragment,verbatim]
 c''4\sostenutoDown d''4 e''4 c'4 f'4 g'4 a'4\sostenutoUp
diff --git a/input/regression/pedal-bracket.ly b/input/regression/pedal-bracket.ly
new file mode 100644
index 0000000000..5f2d7588ef
--- /dev/null
+++ b/input/regression/pedal-bracket.ly
@@ -0,0 +1,24 @@
+
+\header {
+
+    texidoc = "Piano pedal brackets.  Brackets should start and end at
+ the left side of the note. If a note is shared between two brackets,
+ the ends are flared.
+
+There are no vertical endings at a line-break.  " }
+
+\score {
+    \notes \relative c'' {
+        \property Staff.pedalSustainStyle = #'bracket
+
+        c4 d e \sustainDown b c c, \sustainUp \sustainDown  d8[ c]  e8[ 
+	    e \sustainUp \sustainDown] f4 d
+        \sustainUp g \sustainDown b b, \sustainUp c'
+
+        \property Staff.pedalUnaCordaStyle = #'mixed
+
+        c4 d \unaCorda e f g
+        b  | \break c b c \treCorde c
+    }
+    \paper { raggedright = ##t }
+}
diff --git a/input/regression/pedal-ped.ly b/input/regression/pedal-ped.ly
new file mode 100644
index 0000000000..94d31bc196
--- /dev/null
+++ b/input/regression/pedal-ped.ly
@@ -0,0 +1,25 @@
+\header
+{
+    texidoc = "Piano pedals: the standard style is with Ped symbols.
+The string can be tuned. This example shows the shorter tilde/P variant
+at the end of the melody."
+
+}
+
+
+\score{
+    \context Staff \notes\relative c'{
+
+        c4 d e f g
+        \sustainDown b c
+        c, d16[  c  c c]  e[ e \sustainUp \sustainDown e e ] f4 \sustainUp 
+        g\sustainDown  b \sustainUp c 
+        \property Staff.pedalSustainStrings = #'("-" "-P" "P")
+        \property Staff.SustainPedal \override #'padding = #-2
+        c, \sustainDown d e \sustainUp \sustainDown f
+        \sustainUp g b c
+
+
+
+    }
+}
diff --git a/input/test/pedal.ly b/input/test/pedal.ly
deleted file mode 100644
index 6230833d0e..0000000000
--- a/input/test/pedal.ly
+++ /dev/null
@@ -1,33 +0,0 @@
-
-\version "2.1.7"
-
-\header{ texidoc = "@cindex Pedal
-Piano pedal symbols merge stop and start.  The strings are configurable. 
-Text style, bracket style, and a mixture of both are supported.  "
-}
-
-\score{
-    \context Staff \notes\relative c'{
-
-	c4 d e f g
-	\sustainDown b c
-	c,  d16[  c  c c]  e[ e \sustainUp \sustainDown e e ] f4 \sustainUp 
-	g\sustainDown  b \sustainUp c 
-	\property Staff.pedalSustainStrings = #'("-" "-P" "P")
-	\property Staff.SustainPedal \override #'padding = #-2
-	c, \sustainDown d e \sustainUp \sustainDown f
-	\sustainUp g b c
-
-	\property Staff.pedalSustainStyle = #'bracket
-
-	c4 d e \sustainDown b c c, \sustainUp \sustainDown  d8[ c]  e8[ e \sustainUp \sustainDown] f4 d
-	\sustainUp g \sustainDown b b, \sustainUp c'
-
-	\property Staff.pedalUnaCordaStyle = #'mixed
-
-	c4 d \unaCorda e f g
-	b \treCorde c
-
-    }
-}
-
diff --git a/input/test/scales-greek.ly b/input/test/scales-greek.ly
index f99145ea08..d7d4e2ee99 100644
--- a/input/test/scales-greek.ly
+++ b/input/test/scales-greek.ly
@@ -1,52 +1,35 @@
 \version "2.1.7"
 \header {
-  texidoc = "@cindex Scales Greek
-Show different scales."
+  texidoc = "
+
+Show different greek scales. All these scales are in the key of C
+(major, ionian, phrygian, etc.)
+
+"
 }
 
-voicedefault = \notes {
-\property Score.defaultBarType="empty"
+\score  { \notes {
 
 \key c \major c'8 -"major" d'8 e'8 f'8 g'8 a'8 b'8 c''8
 
 \key c \ionian c'8 -"ionian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
 
-\key d \dorian c'8 -"dorian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
-
-\key e \phrygian c'8 -"phrygian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
-
-\key f \lydian c'8 -"lydian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
-
-\key g \mixolydian c'8 -"mixolydian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
-
-\key a \minor c'8 -"minor" d'8 e'8 f'8 g'8 a'8 b'8 c''8
+\transpose d c { \key d \dorian c'8 -"dorian" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
-\key a \aeolian c'8 -"aeolian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
+\transpose e c { \key e \phrygian c'8 -"phrygian" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
-\key b \locrian c'8 -"locrian" d'8 e'8 f'8 g'8 a'8 b'8 c''8
+\transpose f c { \key f \lydian c'8 -"lydian" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
-\key f \major c'8 -"major" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
+\transpose g c  { \key g \mixolydian c'8 -"mixolydian" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
-\key f \ionian c'8 -"ionian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
+\transpose a c' { \key a \minor c'8 -"minor" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
-\key g \dorian c'8 -"dorian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
+\transpose a c' { \key a \aeolian c'8 -"aeolian" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
-\key a \phrygian c'8 -"phrygian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
-
-\key bes \lydian c'8 -"lydian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
-
-\key c \mixolydian c'8 -"mixolydian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
-
-\key d \aeolian c'8 -"aeolian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
-
-\key d \minor c'8 -"minor" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
-
-\key e \locrian c'8 -"locrian" d'8 e'8 f'8 g'8 a'8 bes'8 c''8
+\transpose b c' { \key b \locrian c'8 -"locrian" d'8 e'8 f'8 g'8 a'8 b'8 c''8 }
 
 }
-
-\score{
-	    \voicedefault 
+	  
 	\paper { }
 	\midi {}
 }
diff --git a/input/test/staff-lines.ly b/input/test/staff-lines.ly
index 19fc31b39f..33c5c92303 100644
--- a/input/test/staff-lines.ly
+++ b/input/test/staff-lines.ly
@@ -1,8 +1,11 @@
 
 \version "2.1.7"
 
-\header { texidoc="@cindex Staff Lines
-Set staff symbol property. "
+\header {
+
+    texidoc="@cindex Staff Lines Staff symbol properties may also be
+ set with @code{\\property}. "
+	  
 }
 
 
@@ -20,10 +23,10 @@ lower = \notes\relative c {
       \upper
     >>  
     \new Staff  {
-	\property Staff.StaffSymbol \set #'line-count = #4 } <<
+	\property Staff.StaffSymbol \set #'line-count = #4 
         \clef bass
         \lower
-    >>  
+    }
   >>
   \paper { raggedright=##t}  
 }
diff --git a/input/test/text-spanner.ly b/input/test/text-spanner.ly
index 0f645c5edd..419707368f 100644
--- a/input/test/text-spanner.ly
+++ b/input/test/text-spanner.ly
@@ -1,6 +1,5 @@
 
 \version "2.1.7"
-% TODO: check about other ottava functions.
 
 \header { texidoc = "@cindex text spanner
 You can make LilyPond print text spanners. "
@@ -13,8 +12,8 @@ You can make LilyPond print text spanners. "
 	b c 
         a \stopTextSpan
 
-        \property Voice.TextSpanner \revert #'style
-        \property Voice.TextSpanner \override #'style = #'dotted-line
+        \property Voice.TextSpanner \override #'dash-period = #2
+        \property Voice.TextSpanner \override #'dash-fraction = #0.0
         a \startTextSpan
 	b c 
         a \stopTextSpan
diff --git a/input/test/trill.ly b/input/test/trill.ly
index 8cd763f3fc..9b635e9e3e 100644
--- a/input/test/trill.ly
+++ b/input/test/trill.ly
@@ -1,7 +1,10 @@
 \version "2.1.7"
 
 \header { texidoc="@cindex Trill
-Show trill line type. "
+Show trill line type.
+
+The extended trill is a TextSpanner in @code{trill} style.
+"
 }
 
 
@@ -9,17 +12,19 @@ Show trill line type. "
   \context RhythmicStaff \notes {
     \stemDown
     \property Voice.Stem \override #'transparent = ##t
-    \property Voice.TextSpanner \set #'style = #'dotted-line
+    \property Voice.TextSpanner \set #'dash-fraction = #0.0
+    \property Voice.TextSpanner \set #'dash-period = #1.0
     \property Voice.TextSpanner \set #'edge-height = #'(0 . 1.5)
     \property Voice.TextSpanner \set #'edge-text = #'("bla " . "")
-    a#(ly:export (make-span-event 'TextSpanEvent START)) b c a #(ly:export (make-span-event 'TextSpanEvent STOP))
+    a\startTextSpan b c a\stopTextSpan
+
 
-    %\property Voice.TextSpanner \set #'font-family = #'music
+    %% TODO: should have trill spanner.
     \property Voice.TextSpanner \set #'style = #'trill
     \property Voice.TextSpanner \set #'edge-height = #'(0 . 0)
     \property Voice.TextSpanner \set #'edge-text
      = #(cons (make-musicglyph-markup "scripts-trill")  "")
-    a#(ly:export (make-span-event 'TextSpanEvent START)) b c a #(ly:export (make-span-event 'TextSpanEvent STOP))
+    a\startTextSpan b c a\stopTextSpan
   }
 	\paper { raggedright = ##t} 
 }
diff --git a/lily/line-interface.cc b/lily/line-interface.cc
index 3340c8190d..a4adb8e357 100644
--- a/lily/line-interface.cc
+++ b/lily/line-interface.cc
@@ -64,22 +64,23 @@ Line_interface::make_line (Real th, Offset from, Offset to)
   return Molecule (box, at);
 }
 
-
-/*
-  TODO: read THICK from ME
- */
 Molecule
 Line_interface::line (Grob *me, Offset from, Offset to)
 {
-  Real thick = Staff_symbol_referencer::line_thickness (me);
+  Real thick = Staff_symbol_referencer::line_thickness (me)
+    * robust_scm2double (me->get_grob_property ("thickness"),1);
+  
   SCM type = me->get_grob_property ("style");
 
   SCM dash_fraction = me->get_grob_property ("dash-fraction");
   if (gh_number_p (dash_fraction) || type == ly_symbol2scm ("dotted-line"))
     {
-      Real fraction =
-	robust_scm2double (dash_fraction, (type == ly_symbol2scm ("dotted-line")) ? 0.0 : 0.4);
-
+      
+      Real fraction
+	= type == ly_symbol2scm ("dotted-line")
+	? 0.0
+	: robust_scm2double (dash_fraction, 0.4);
+      
       fraction = (fraction >? 0) <? 1.0;
       Real period = Staff_symbol_referencer::staff_space (me)
 	* robust_scm2double (me->get_grob_property ("dash-period"), 1.0);
@@ -96,5 +97,11 @@ Line_interface::line (Grob *me, Offset from, Offset to)
 }
 
 ADD_INTERFACE(Line_interface, "line-interface",
-	      "Generic line objects. Any object using lines supports this. ",
+	      "Generic line objects. Any object using lines supports this.  Normally,"
+	      "you get a straight line. If dash-period is defined, a dashed line is "
+	      "produced; the length of the dashes is tuned with" 
+	      "@code{dash-fraction}. If the latter is set to 0, a dotted line is "
+	      "produced. If @code{dash-fraction} is negative, the line is set "
+	      "transparent.",
+	      
 	      "dash-period dash-fraction thickness style")
diff --git a/lily/piano-pedal-bracket.cc b/lily/piano-pedal-bracket.cc
index 0920330324..362ff2a2ae 100644
--- a/lily/piano-pedal-bracket.cc
+++ b/lily/piano-pedal-bracket.cc
@@ -5,95 +5,87 @@ source file of the GNU LilyPond music typesetter
 
 (c) 2003 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-based on smouldering remains by
-
-   Chris Jackson <chris@fluffhouse.org.uk>
-
-
-*/
-/* 
-   Piano pedal brackets are a special case of a text spanner.
-   Pedal up-down (restart) indicated by the angled right and left edges 
-   of consecutive pedals touching exactly to form an __/\__
-
 */
 
-
-/*
-  TODO: this should be moved somewhere else (?).
-
-  Perhaps make separate function for pedal-bracket.
- */
 #include "molecule.hh"
 #include "spanner.hh"
 #include "item.hh"
-#include "paper-def.hh"
+#include "tuplet-bracket.hh"
 
 struct Piano_pedal_bracket
 {
-  DECLARE_SCHEME_CALLBACK(after_line_breaking,(SCM));
+  DECLARE_SCHEME_CALLBACK(brew_molecule,(SCM));
   static bool has_interface (Grob*);
 };
 
-ADD_INTERFACE (Piano_pedal_bracket,"piano-pedal-bracket-interface",
-	       "",
-	       "pedal-text");
 
-MAKE_SCHEME_CALLBACK(Piano_pedal_bracket,after_line_breaking,1);
+MAKE_SCHEME_CALLBACK(Piano_pedal_bracket,brew_molecule,1);
 SCM
-Piano_pedal_bracket::after_line_breaking (SCM smob)
+Piano_pedal_bracket::brew_molecule (SCM smob)
 {
   Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
-
-  Drul_array<bool> broken;
-  Drul_array<Real> height(0,0), shorten(0,0);
-
-  SCM eh = me->get_grob_property ("edge-height");
-  SCM sp = me->get_grob_property ("shorten-pair");
   
+  Drul_array<bool> broken (false,false);
+  Drul_array<Real> height = robust_scm2drul
+    (me->get_grob_property ("edge-height"), Interval (0,0));
+  Drul_array<Real> shorten = robust_scm2drul
+    (me->get_grob_property ("shorten-pair"), Interval (0,0));
+  Drul_array<Real> flare = robust_scm2drul
+    (me->get_grob_property ("bracket-flare"), Interval (0,0));
+
+  Grob *common = me->get_bound (LEFT)
+    ->common_refpoint (me->get_bound (RIGHT), X_AXIS);
+  Grob *textbit = unsmob_grob (me->get_grob_property("pedal-text"));
+
+  if (textbit)
+    common = common->common_refpoint (textbit, X_AXIS);
+
+  Interval span_points (0,0);
   Direction d = LEFT;
-
   do
     {
       Item *b = me->get_bound (d);
       broken[d] = b->break_status_dir () != CENTER;
+      if (broken[d])
+	height[d] = 0.0;
 
-      if (!broken[d] && (is_number_pair (eh)))
-	height[d] += gh_scm2double (index_get_cell (eh, d));
-      if (is_number_pair (sp))
-	shorten[d] +=  gh_scm2double (index_get_cell (sp, d));
+      Interval ext   = b->extent (common,  X_AXIS);
+      span_points[d] = ext [broken[d] ?  RIGHT : LEFT];
     }
   while (flip (&d) != LEFT);
+
   
   /* For 'Mixed' style pedals, i.e.  a bracket preceded by text:  Ped._____|
    need to shorten by the extent of the text grob
-
-
-   Urg. - why not hang bracket between text items? --hwn
   */
-  if (Grob *textbit = unsmob_grob (me->get_grob_property("pedal-text")))
+  if (textbit)
     {
       height[LEFT] = 0;
-      SCM pa = me->get_grob_property ("if-text-padding"); // UGH.
-      Real padding =0.;
-      if (gh_number_p (pa))
-	padding = gh_scm2double (pa);
-	  
-      shorten[LEFT] += padding + textbit->extent (textbit, X_AXIS)[RIGHT];
+      
+      Real padding = robust_scm2double (me->get_grob_property ("if-text-padding"), 0);
+      
+      span_points[LEFT] = padding
+	+ textbit->extent (common, X_AXIS)[RIGHT];
     }
   
-  if (broken[LEFT])
+
+  Molecule m ;
+  if (!span_points.is_empty () &&
+      span_points.length () > 0.001)
     {
-      shorten[LEFT]  -=  me->get_broken_left_end_align () ;
+      m = Tuplet_bracket::make_bracket (me, Y_AXIS,
+					Offset (span_points.length (), 0),
+					height,
+					0.0,
+					flare, shorten);
     }
+  m.translate_axis (span_points[LEFT]
+		    - me->relative_coordinate (common, X_AXIS), X_AXIS);
+  return m.smobbed_copy ();
+}
 
-  // Also shorten so that it ends just before the spanned note.
-  Grob  *rb = me->get_bound (RIGHT);
-  shorten[RIGHT]  += rb->extent (rb, X_AXIS)[RIGHT];
-    
-  me->set_grob_property ("edge-height", ly_interval2scm (height));
-  me->set_grob_property ("shorten-pair", ly_interval2scm (shorten));
 
-  return SCM_UNSPECIFIED;
-}
 
+ADD_INTERFACE (Piano_pedal_bracket,"piano-pedal-bracket-interface",
+	       "The bracket of the piano pedal.  It can be tuned through the regular bracket properties (bracket-flare, edge-height, shorten-pair).",
+	       "edge-height shorten-pair bracket-flare pedal-text");
diff --git a/lily/piano-pedal-engraver.cc b/lily/piano-pedal-engraver.cc
index 0b4f957b9d..0a9ddd1602 100644
--- a/lily/piano-pedal-engraver.cc
+++ b/lily/piano-pedal-engraver.cc
@@ -23,6 +23,11 @@
 #include "note-column.hh"
 #include "warn.hh"
 
+/*
+  Urgh. This engraver is too complex. rewrite. --hwn
+
+*/
+
 struct Pedal_info
 {
   char const * name_;
@@ -31,6 +36,7 @@ struct Pedal_info
     Event for currently running pedal.
   */
   Music* current_bracket_ev_;
+
   /*
     Event for currently starting pedal, (necessary?
     
@@ -81,8 +87,6 @@ private:
   
   Link_array<Spanner> previous_;
   
-
-  
   void create_text_grobs (Pedal_info *p, bool);
   void create_bracket_grobs (Pedal_info *p, bool);
   void typeset_all ();
@@ -145,8 +149,9 @@ Piano_pedal_engraver::acknowledge_grob (Grob_info info)
 	      add_bound_item (p->line_spanner_,info.grob_);
 	    }	  
 	  if (p->bracket_)
-	    add_bound_item (p->bracket_,info.grob_);		  
-	  
+	    add_bound_item (p->bracket_,info.grob_);
+	  if (p->finished_bracket_)
+	    add_bound_item (p->finished_bracket_,info.grob_);		  
 	}
     }
 }
@@ -195,7 +200,6 @@ Piano_pedal_engraver::process_music ()
 	      String name  = String (p->name_) + "PedalLineSpanner";
 	      p->line_spanner_ = new Spanner (get_property (name.to_str0 ()));
 
-	      
 	      Music * rq = (p->event_drul_[START]  ?  p->event_drul_[START]  :  p->event_drul_[STOP]);
 	      announce_grob (p->line_spanner_, rq->self_scm ());
 	    }
@@ -344,7 +348,9 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed)
       assert (!p->finished_bracket_); 
 
       Grob *cmc = unsmob_grob (get_property ("currentMusicalColumn"));
-      p->bracket_->set_bound (RIGHT, cmc);
+
+      if (!p->bracket_->get_bound (RIGHT))
+	p->bracket_->set_bound (RIGHT, cmc);
 
       /*
 	Set properties so that the molecule-creating function will
@@ -516,12 +522,9 @@ Piano_pedal_engraver::typeset_all ()
 	  /*
 	    Hmm.
 	  */
-	  if (p->name_ != String ("Sustain"))
+	  if (p->name_ != String ("Sustain") && sustain)
 	    {
-	      if (sustain)
-		{
-		  Side_position_interface::add_support (p->item_,sustain);
-		}
+	      Side_position_interface::add_support (p->item_,sustain);
 	    }
 	  typeset_grob (p->item_);
 	  p->item_ = 0;
@@ -536,6 +539,7 @@ Piano_pedal_engraver::typeset_all ()
 	    }
 
 	  typeset_grob (p->finished_bracket_);
+	  
 	  p->finished_bracket_ =0;
 	}
 
diff --git a/lily/text-spanner.cc b/lily/text-spanner.cc
index 994019c76f..aa5ac971e6 100644
--- a/lily/text-spanner.cc
+++ b/lily/text-spanner.cc
@@ -64,8 +64,8 @@ Text_spanner::brew_molecule (SCM smob)
 	}
       else
 	  {
-	    bool encl = to_boolean (me->get_grob_property ("enclose-bounds"));
-	    span_points[d] = b->extent (common, X_AXIS)[encl ? d : -d];
+	    Real encl = robust_scm2double (me->get_grob_property ("enclose-bounds"), 0.0);
+	    span_points[d] = b->extent (common, X_AXIS).linear_combination (d * encl);
 
 	    if (is_number_pair (shorten))
 	      span_points -= d * gh_scm2double (index_get_cell (shorten, d));
diff --git a/lily/tie-column.cc b/lily/tie-column.cc
index a9eddaebe9..17531f1fa7 100644
--- a/lily/tie-column.cc
+++ b/lily/tie-column.cc
@@ -153,8 +153,10 @@ Tie_column::werner_directions (Grob *me)
   
   if (ties.size () == 1)
     {
-      Grob *  t = ties[0];      
-      set_grob_direction (t,Tie::get_default_dir (t));
+      Grob *  t = ties[0];
+      if (t->live ()
+	  && !get_grob_direction (t))
+	set_grob_direction (t,Tie::get_default_dir (t));
       return ;
     }
 
diff --git a/lily/tie.cc b/lily/tie.cc
index 4e935c9555..1fba2e1ff4 100644
--- a/lily/tie.cc
+++ b/lily/tie.cc
@@ -58,9 +58,11 @@ Grob*
 Tie::head (Grob*me, Direction d) 
 {
   SCM c = me->get_grob_property ("head-pair");
-  c = index_get_cell (c, d);
 
-  return unsmob_grob (c);
+  if (gh_pair_p)
+    return unsmob_grob (index_get_cell (c, d));
+  else
+    return 0;
 }
 
 Real
@@ -134,7 +136,7 @@ Tie::get_control_points (SCM smob)
     {
       programming_error ("Tie without heads.");
       me->suicide ();
-      return SCM_UNSPECIFIED;
+      return SCM_EOL;
     }
 
   set_direction (me);
@@ -324,11 +326,14 @@ Tie::brew_molecule (SCM smob)
   Grob*me = unsmob_grob (smob);
 
   SCM cp = me->get_grob_property ("control-points");
-  if (cp == SCM_EOL)
+  if (!gh_pair_p (cp))		// list is more accurate
     {
       cp = get_control_points (smob);
       me->set_grob_property ("control-points", cp);
     }
+
+  if (!gh_pair_p (cp))
+    return Molecule ().smobbed_copy ();
   
   Real thick
     = Staff_symbol_referencer::line_thickness (me)
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 7fda470fb6..e34e063285 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -371,7 +371,10 @@ provided in @code{input/regression/molecule-hacking.ly}.
 (grob-property-description 'note-heads grob-list? "List of note head grobs")
 (grob-property-description 'old-accidentals list? "list of (pitch, accidental) pairs.")
 (grob-property-description 'oriscus boolean? "is this neume an oriscus?.")
-(grob-property-description 'enclose-bounds boolean? "whether a text spanner should extend to the outer edge of the spanned notes")
+
+(grob-property-description 'enclose-bounds number?
+"How much of the bound a spanner  should enclose: +1 = completely, 0 = center, -1 not at all.")
+
 (grob-property-description 'padding ly:dimension? "add this much extra space between objects that are next to each other.")
 (grob-property-description 'pedal-text ly:grob? "Pointer to the text of a mixed-style piano pedal.")
 (grob-property-description 'penalty number? "Penalty for breaking at
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index ac2e7f7cb3..8e04506c20 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -719,18 +719,17 @@
 
     (PianoPedalBracket   ;; an example of a text spanner
      . (
-	(molecule-callback . ,Text_spanner::brew_molecule)
-	(after-line-breaking-callback . ,Piano_pedal_bracket::after_line_breaking)
+	(molecule-callback . ,Piano_pedal_bracket::brew_molecule)
 	(font-family . roman)
 	(style . line)
 	(if-text-padding . 1.0)
-	(enclose-bounds . #t)
+	(enclose-bounds . -1.0)
 	(direction . -1)
 	(bracket-flare . (0.5 . 0.5))
 	(edge-height . (1.0 . 1.0))
 	(shorten-pair . (0.0 . 0.0))
 	(thickness .  1.0)
-	(meta . ((interfaces . (text-spanner-interface piano-pedal-interface piano-pedal-bracket-interface spanner-interface))))
+	(meta . ((interfaces . (line-interface piano-pedal-interface piano-pedal-bracket-interface spanner-interface))))
 	))
 
     (RepeatSlash
@@ -1084,7 +1083,7 @@
 	(shorten-pair . (0.0 . -0.6))
 	(staff-padding . 1.0)
 	(padding  . 0.5)
-	(enclose-bounds . #t)
+	(enclose-bounds . 1)
 	(minimum-length . 1.0)
 	(dash-fraction . 0.3)
 	(edge-height . (0 . 1.2))
diff --git a/scm/lily.scm b/scm/lily.scm
index 822fe1f463..ab464ec08b 100644
--- a/scm/lily.scm
+++ b/scm/lily.scm
@@ -176,14 +176,20 @@
 
 
 ;; TODO: use the srfi-1 partition function.
-(define-public (uniq-list list)
+(define-public (uniq-list l)
+  
   "Uniq LIST, assuming that it is sorted"
-  (if (null? list) '()
-      (if (null? (cdr list))
-	  list
-	  (if (equal? (car list) (cadr list))
-	      (uniq-list (cdr list))
-	      (cons (car list) (uniq-list (cdr list)))))))
+  (define (helper acc l) 
+    (if (null? l)
+	acc
+	(if (null? (cdr l))
+	    (cons (car l) acc)
+	    (if (equal? (car l) (cadr l))
+		(helper acc (cdr l))
+		(helper (cons (car l) acc)  (cdr l)))
+	    )))
+  (reverse! (helper '() l) '()))
+
 
 (define (split-at-predicate predicate l)
  "Split L = (a_1 a_2 ... a_k b_1 ... b_k)
diff --git a/scm/music-functions.scm b/scm/music-functions.scm
index 46b29e8207..4ee6dcd4a9 100644
--- a/scm/music-functions.scm
+++ b/scm/music-functions.scm
@@ -821,7 +821,6 @@ Rest can contain a list of beat groupings
     (ly:set-mus-property! m2 'property-operations props)
     (ly:run-translator m2 part-combine-listener)
     (ly:run-translator m1 part-combine-listener)
-    (display noticed)
     (ly:set-mus-property! m 'split-list
 			 (determine-split-list (reverse (cdr (assoc "one" noticed)))
 					       (reverse (cdr (assoc "two" noticed)))))
@@ -831,6 +830,11 @@ Rest can contain a list of beat groupings
 
 
 
+;;
+;; due to a bug in the GUILE evaluator,
+;; stack traces result in core dumps.
+;; therefore we retain debugging code.
+;;
 (define-public (determine-split-list evl1 evl2)
   "EVL1 and EVL2 should be ascending"
   
@@ -846,7 +850,7 @@ Rest can contain a list of beat groupings
   (define result
     (list->vector
      (map (lambda (x)
-	    (cons x 'together))
+	    (cons x '()))
 	  (uniq-list
 	  (merge (map car evl1) (map car evl2) ly:moment<?)))))
 
@@ -860,7 +864,7 @@ Rest can contain a list of beat groupings
 	    ((name (ly:get-mus-property ev 'name))
 	     (key (cond
 		   ((equal? name 'SlurEvent) 'slur)
-		   ((equal? name 'TieEvent) 'tie)
+		   ((equal? name 'PhrasingSlurEvent) 'tie)
 		   ((equal? name 'Beam) 'beam)
 		   (else #f)))
 	     (sp (ly:get-mus-property ev 'span-direction)))
@@ -886,21 +890,24 @@ Rest can contain a list of beat groupings
       (set-cdr! (vector-ref result (if (pair? index)
 				       (car index) ri)) x) )
 
-;    (display (list ri i1 i2 active1 active2 "\n"))
+;    (display (list i1 i2 ri active1 active2 (vector-length ev1) (vector-length ev2) (vector-length result)  "\n"))
     (cond
      ((= ri (vector-length result)) '())
      ((= i1 (vector-length ev1)) (put 'apart))
      ((= i2 (vector-length ev2)) (put 'apart))
      (else
       (let*
-	  ((m1 (when ev1 i1))
+	  (
+;	   (x (display (list "\nelse" (= i1 (vector-length ev1)) i2  (vector-length ev2) (= i2 (vector-length ev2)))))
+	   (m1 (when ev1 i1))
 	   (m2 (when ev2 i2))
+;	   (x (display "oked"))
 	   (new-active1
 	    (sort
 	     (analyse-span-events active1 (map car (what ev1 i1)))
 	     symbol<?))
 	   (new-active2
-	    (sort (analyse-span-events active2 (map car (what ev2 i1)))
+	    (sort (analyse-span-events active2 (map car (what ev2 i2)))
 		  symbol<?)))
 	
 	(if (not (or (equal? m1 (when result ri))
@@ -934,10 +941,14 @@ Rest can contain a list of beat groupings
 		   )
 		(cond
 		 ((equal? pitches1 pitches2) (put 'unisono))
+		 ((= (length notes1) 0) (put 'solo2))
+		 ((= (length notes2) 0) (put 'solo1))
 		 ((> (length notes1) 1) (put 'apart))
 		 ((> (length notes2) 1) (put 'apart))
 		 (else
-		  (let* ((diff (ly:pitch-diff (car pitches1) (car pitches2))))
+		  (let* (
+;			 (bla (display (list (length pitches1) (length pitches2))))
+			 (diff (ly:pitch-diff (car pitches1) (car pitches2))))
 		    (if (< (ly:pitch-steps diff) chord-threshold)
 			(put 'chords)
 			(put 'apart))
diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py
index 02bafe9148..3fa5f33f6c 100644
--- a/scripts/convert-ly.py
+++ b/scripts/convert-ly.py
@@ -1700,6 +1700,12 @@ def conv (str):
 
 conversions.append (((2,1,13), conv, """set-staff-size -> set-global-staff-size"""))
 
+def conv (str):
+	str =re.sub (r"#'style\s*=\s*#'dotted-line",
+		     r"#'dash-fraction = #0.0 ", str)
+	return str
+
+conversions.append (((2,1,14), conv, """style = dotted -> dash-fraction = 0"""))
 
 ################################
 #	END OF CONVERSIONS