From 01e85a02b5866e42e2ef822797f3986f06289bc0 Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Wed, 23 Feb 2000 14:56:26 +0100
Subject: [PATCH] release: 1.3.26

===========

* lilypond as as2ly: --help and --version to stdout.  Regular identify
  to stderr.  This fixes help2man's manpage generation.

* configure: substitute full path for perl and guile in scripts.

* Added ascii slur and volta.  There seems to be a Lily bug in volta placement.

* Bugfix: default font now user settable

* as2text: handle plain ascii font, read from stdin, you can now do:

  echo "\time 4/4; g''1 g2 g4. g8" | lilypond -f as -i init-as.fly - | as2text

1.3.25.h
---
 CHANGES                                       | 26 +++--
 Documentation/faq.texi                        |  2 +-
 Documentation/programmer/regression-test.tely |  6 ++
 Documentation/topdocs/index.tely              | 30 ++++--
 Documentation/user/properties.itely           | 13 +++
 TODO                                          |  5 +
 VERSION                                       |  4 +-
 configure                                     | 99 +++++++++++++------
 input/test/tie-chord.ly                       | 11 +++
 lily/bar.cc                                   | 23 ++---
 lily/clef-item.cc                             | 13 ++-
 lily/group-interface.cc                       |  7 ++
 lily/include/directional-element.hh           |  2 -
 lily/include/group-interface.hh               |  1 +
 lily/include/request-iterator.hh              | 24 +++++
 lily/include/side-position-interface.hh       |  3 +-
 lily/include/tie-column.hh                    |  2 +-
 lily/include/tie-engraver.hh                  | 49 ---------
 lily/include/tie.hh                           |  4 +-
 lily/include/translator-group.hh              |  8 +-
 lily/music-iterator.cc                        |  7 +-
 lily/request-chord-iterator.cc                |  1 -
 lily/request-iterator.cc                      | 29 ++++++
 lily/score-element.cc                         |  4 +-
 lily/side-position-interface.cc               | 40 ++++++--
 lily/tie-column.cc                            | 70 ++++++++++++-
 lily/tie-engraver.cc                          | 67 ++++++++++++-
 lily/tie.cc                                   | 16 +--
 make/out/lilypond.lsm                         |  8 +-
 make/out/lilypond.spec                        |  4 +-
 scm/generic-property.scm                      |  6 ++
 scm/lily.scm                                  |  2 +-
 32 files changed, 427 insertions(+), 159 deletions(-)
 create mode 100644 input/test/tie-chord.ly
 delete mode 100644 lily/include/directional-element.hh
 create mode 100644 lily/include/request-iterator.hh
 create mode 100644 lily/request-iterator.cc

diff --git a/CHANGES b/CHANGES
index fbbf8f0bf8..5904ba5aee 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,35 +6,33 @@
 
 * configure: substitute full path for perl and guile in scripts.
 
-1.3.25.jcn1
-===========
-
 * Added ascii slur and volta.  There seems to be a Lily bug in volta placement.
 
-* Bugfix: print identification string 'GNU LilyPond ...' onto stderr
-
 * Bugfix: default font now user settable
 
 * as2text: handle plain ascii font, read from stdin, you can now do:
 
   echo "\time 4/4; g''1 g2 g4. g8" | lilypond -f as -i init-as.fly - | as2text
 
-1.3.24.jcn4
+1.3.25.hwn1
 ===========
 
-* as2text: catch missing font/character errors, added default font, set text.
+* Bugfix: second half of broken ties now are displayed again.
 
-1.3.24.jcn3
-===========
+* Bugfix: add clef to the support of 8 text in the G_8 clefs. Center
+it horizontally on the clef.
 
-* New ascii fonts: as5 as-numeral4 as-braces9
+* Added Tie_column spanner. Ties in tied chords now get proper directionsa.
 
-* Fixes to as2text.scm
+* Bugfix: unbroken repeat barlines now work, eg. |:
 
-* Added lots of ascii glyphs
+* Added Request_iterator to make more flexible constructions possible.
 
-1.3.24.jcn2
-===========
+1.3.25
+======
+* as2text: catch missing font/character errors, added default font, set text.
+
+* New ascii fonts and glyphs: as5 as-numeral4 as-braces9
 
 * Ascii output, minimal support:
   - AsciiScript Fonts: mf/*.af
diff --git a/Documentation/faq.texi b/Documentation/faq.texi
index 02bd7b5994..835c1790dc 100644
--- a/Documentation/faq.texi
+++ b/Documentation/faq.texi
@@ -370,7 +370,7 @@ You should use dvips and ghostscript to print the @code{dvi} output: the
 slurs and beams are PS @code{\special} commands.
 
 
-subsubsection My symbols are all messed up after I upgraded, I get the wrong symbols and dvi-checksum errors!
+@subsubsection My symbols are all messed up after I upgraded, I get the wrong symbols and dvi-checksum errors!
 
 We obviously mucked with the fonts in the upgrade.  Remove @emph{all}
 previous fonts, including the @file{.pk} and @file{.tfm} fonts in
diff --git a/Documentation/programmer/regression-test.tely b/Documentation/programmer/regression-test.tely
index dee4b30c7e..b0f0718039 100644
--- a/Documentation/programmer/regression-test.tely
+++ b/Documentation/programmer/regression-test.tely
@@ -148,6 +148,12 @@ The horizontal middle should not overlap with a staffline.
 
 @mudelafile{tie.ly}
 
+When tieing chords, the outer slurs point outwards, the inner slurs
+point away from the center of the staff.  Override with
+@code{tieVerticalDirection}.
+
+@mudelafile{tie-chord.ly}
+
 When tieing notes with accidentals across a bar boundary, the accidental
 must not be drawn on the note in the new bar.  Instead, the next note of
 the same pitch in this bar should always show the accidental (even if
diff --git a/Documentation/topdocs/index.tely b/Documentation/topdocs/index.tely
index ce44ea54dd..38360739ad 100644
--- a/Documentation/topdocs/index.tely
+++ b/Documentation/topdocs/index.tely
@@ -6,7 +6,7 @@
 @top
 
 
-@unnumbered LilyPond -- The GNU Project Music Typesetter
+@unnumberedsec LilyPond -- The GNU Project Music Typesetter
 
 
 @html
@@ -15,27 +15,39 @@
 
 @c something breaks on 3.12 f
 
+@unnumberedsec What is LilyPond?
+
 LilyPond is a music typesetter.  It produces beautiful sheet music using
 a high level description file as input. It excels at typesetting
 classical music, but you can also print pop-songs.  With LilyPond we
 hope to make music publication software available to anyone on the
 internet.
 
-The program also has limited MIDI functionality: you can write MIDI
-files with lilypond, and we have a simple MIDI to lilypond conversion
-tool, @file{midi2ly}.
-
-LilyPond is free software. It is licensed under GNU General Public
-License, and it is part of the @uref{http://www.gnu.org/,GNU Project}.
+@unnumberedsec Why should I use it?
 
+The input to LilyPond is plain text. So you can use your favorite text
+editor to edit it, you can put it in mail or embed it in an article like
+this:
 
 @quotation
-@mudela[fragment]
+@mudela[fragment,verbatim]
 	\relative c'' { \key es; r8 [c16 b] [c8 g] [as c16 b] [c8 d] | g,4 }
 @end mudela 
 @end quotation
 
-    
+The output looks very good: the font and the layout algorithms were
+inspired by engraved music, so you can expect that same clear and
+elegant look from your LilyPond output.  And if you don't like the
+looks, you can tweak almost everything.
+
+The program also has limited MIDI functionality: you can write MIDI
+files with lilypond, and we have a simple MIDI to lilypond conversion
+tool, @file{midi2ly}.
+
+LilyPond is free software. It is licensed under GNU General Public
+License, so you can use, modify and redistribute the program almost no
+restrictions.  LilyPond is part of the @uref{http://www.gnu.org/,GNU
+Project}.
 
 The version numbers are in Linux-kernel style: even unnumbered versions
 are `stable'. The webpages for the stable version reside at GNU, here:
diff --git a/Documentation/user/properties.itely b/Documentation/user/properties.itely
index 41db30bb48..cfa19c28ff 100644
--- a/Documentation/user/properties.itely
+++ b/Documentation/user/properties.itely
@@ -589,6 +589,19 @@ r1 r1*3 R1*3\property Score.skipBars=1 r1*3 R1*3
 @end mudela
     @end quotation
 
+@item @code{breakAlignOrder}@indexcode{breakAlignOrder} @propertytype{list of string}
+
+   Defines the order in which prefatory matter (clefs, key signatures) appears, eg. this puts the key signatures after the bar lines:
+@example
+	\property Score.breakAlignOrder = #'(
+	  "Span_bar"
+	  "Breathing_sign"
+	  "Clef_item"
+	  "Staff_bar"
+	  "Key_item"
+	  "Time_signature"
+	)
+@end example
 @end table
 
 
diff --git a/TODO b/TODO
index 4833512d78..cdde07acc9 100644
--- a/TODO
+++ b/TODO
@@ -62,6 +62,11 @@ John
 . * junk -M ? 
 . * mudela-book doco
 . * bracket pdf hack
+. * Added StaffContents and RhythmicStaffContents context, they are
+between Staff (which groups the elements), and generates the Staff
+level elements (key, clef, meter, etc). This construction makes
+\consistsend redundant
+
 . * Mondrup:
 - if I change the property minVerticalAlign in a multi staff score with
 lyrics the change affects the lyrics too. I would like the change to
diff --git a/VERSION b/VERSION
index ba81df2fe1..87d3037b52 100644
--- a/VERSION
+++ b/VERSION
@@ -1,8 +1,8 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
-PATCH_LEVEL=25
-MY_PATCH_LEVEL=jcn2
+PATCH_LEVEL=26
+MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff --git a/configure b/configure
index 394dda912c..0a7d64833e 100755
--- a/configure
+++ b/configure
@@ -2653,11 +2653,48 @@ echo "configure:2640: checking for Guile" >&5
     warn_b=yes
 
     fi
+    # Extract the first word of "guile", so it can be a program name with args.
+set dummy guile; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2660: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GUILE'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GUILE" in
+  /*)
+  ac_cv_path_GUILE="$GUILE" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_GUILE="$GUILE" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GUILE="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GUILE" && ac_cv_path_GUILE="error"
+  ;;
+esac
+fi
+GUILE="$ac_cv_path_GUILE"
+if test -n "$GUILE"; then
+  echo "$ac_t""$GUILE" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    
 
 
 
 echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:2661: checking for 8-bit clean memcmp" >&5
+echo "configure:2698: checking for 8-bit clean memcmp" >&5
 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2665,7 +2702,7 @@ else
   ac_cv_func_memcmp_clean=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 2669 "configure"
+#line 2706 "configure"
 #include "confdefs.h"
 #ifdef __cplusplus
 extern "C" void exit(int);
@@ -2678,7 +2715,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:2682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2719: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_memcmp_clean=yes
 else
@@ -2696,12 +2733,12 @@ echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
 test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
 
 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:2700: checking for vprintf" >&5
+echo "configure:2737: checking for vprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2705 "configure"
+#line 2742 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -2727,7 +2764,7 @@ vprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2731: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vprintf=yes"
 else
@@ -2751,12 +2788,12 @@ fi
 
 if test "$ac_cv_func_vprintf" != yes; then
 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:2755: checking for _doprnt" >&5
+echo "configure:2792: checking for _doprnt" >&5
 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2760 "configure"
+#line 2797 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -2782,7 +2819,7 @@ _doprnt();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func__doprnt=yes"
 else
@@ -2809,12 +2846,12 @@ fi
 for ac_func in memmem snprintf vsnprintf gettext
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2813: checking for $ac_func" >&5
+echo "configure:2850: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2818 "configure"
+#line 2855 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2840,7 +2877,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2879,7 +2916,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2883: checking for $ac_word" >&5
+echo "configure:2920: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2909,41 +2946,42 @@ test -n "$MAKEINFO" && break
 done
 test -n "$MAKEINFO" || MAKEINFO="error"
 
-for ac_prog in perl
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2918: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then
+echo "configure:2953: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test -n "$PERL"; then
-  ac_cv_prog_PERL="$PERL" # Let the user override the test.
-else
+  case "$PERL" in
+  /*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path.
+  ;;
+  *)
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
+  for ac_dir in $ac_dummy; do 
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_PERL="$ac_prog"
+      ac_cv_path_PERL="$ac_dir/$ac_word"
       break
     fi
   done
   IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="error"
+  ;;
+esac
 fi
-fi
-PERL="$ac_cv_prog_PERL"
+PERL="$ac_cv_path_PERL"
 if test -n "$PERL"; then
   echo "$ac_t""$PERL" 1>&6
 else
   echo "$ac_t""no" 1>&6
 fi
 
-test -n "$PERL" && break
-done
-test -n "$PERL" || PERL="error"
-
 
 
 
@@ -3138,6 +3176,7 @@ s%@KPSEWHICH@%$KPSEWHICH%g
 s%@TEX_TFMDIR@%$TEX_TFMDIR%g
 s%@GUILE_CFLAGS@%$GUILE_CFLAGS%g
 s%@GUILE_LDFLAGS@%$GUILE_LDFLAGS%g
+s%@GUILE@%$GUILE%g
 s%@LIBOBJS@%$LIBOBJS%g
 s%@MAKEINFO@%$MAKEINFO%g
 s%@PERL@%$PERL%g
diff --git a/input/test/tie-chord.ly b/input/test/tie-chord.ly
new file mode 100644
index 0000000000..662b8a8269
--- /dev/null
+++ b/input/test/tie-chord.ly
@@ -0,0 +1,11 @@
+t = \notes \relative c' {   <c e g> ~ <c e g> }
+
+	\score { 
+\notes \context Voice {
+   \t
+   \transpose g' \t
+   \property Voice.tieVerticalDirection = #-1
+   \t
+
+  }
+}
diff --git a/lily/bar.cc b/lily/bar.cc
index cfbecaa645..90de71251c 100644
--- a/lily/bar.cc
+++ b/lily/bar.cc
@@ -45,28 +45,23 @@ void
 Bar::do_pre_processing ()
 {
   SCM g = get_elt_property ("glyph");
-  SCM breakdir = gh_int2scm (break_status_dir ());
-  
+  Direction bsd = break_status_dir ();
   if (gh_string_p (g))
     {
-      g = scm_eval (gh_list (ly_symbol2scm ("break-barline"),
-			     g,
-			     breakdir,
-			     SCM_UNDEFINED));
+      if (bsd)
+	{
+	  SCM breakdir = gh_int2scm (bsd);
+	  g = scm_eval (gh_list (ly_symbol2scm ("break-barline"),
+				 g,
+				 breakdir,
+				 SCM_UNDEFINED));
+	}
     }
   else
     {
       g = SCM_UNDEFINED;
     }
   
-#if 0  
-  if (remove_elt_property ("at-line-start") == SCM_BOOL_T	// UGR.
-      && (break_status_dir () == RIGHT) && (type_str_ == ""))
-    {
-      type_str_ = "|";
-    }
-#endif
-  
   if (!gh_string_p (g))
     {
       set_elt_property ("transparent", SCM_BOOL_T);
diff --git a/lily/clef-item.cc b/lily/clef-item.cc
index c63e38b4ec..35f4d46bf3 100644
--- a/lily/clef-item.cc
+++ b/lily/clef-item.cc
@@ -16,6 +16,7 @@
 #include "paper-score.hh"
 #include "dimension-cache.hh"
 #include "side-position-interface.hh"
+#include "warn.hh"
 
 void
 Clef_item::do_pre_processing()
@@ -37,6 +38,10 @@ Clef_item::do_pre_processing()
       s = "clefs-" +  s;
       set_elt_property ("glyph", ly_str02scm (s.ch_C()));
     }
+  else
+    {
+      set_elt_property ("transparent", SCM_BOOL_T);
+    }
   
   if (style == "transparent")	// UGH. JUNKME
     {
@@ -62,10 +67,16 @@ Clef_item::do_add_processing ()
 	  
 	  pscore_l_->typeset_element (g);
       
+	  spi.add_support (this);
 	  g->set_elt_property ("text", ly_str02scm ( "8"));
 	  g->set_elt_property ("style", gh_str02scm ("italic"));
 	  g->set_parent (this, Y_AXIS);
-	  g->set_parent (this, X_AXIS);	  
+	  g->set_parent (this, X_AXIS);
+	  
+	  g->set_elt_property ("self-alignment-X", gh_int2scm (0));
+	  g->dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::aligned_on_self);
+	  g->dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::centered_on_parent);
+	  
 	  g->set_elt_property ("direction", octave_dir);
 	  
 	  add_dependency (g);	// just to be sure.
diff --git a/lily/group-interface.cc b/lily/group-interface.cc
index 3b6b53e664..d9ae970c19 100644
--- a/lily/group-interface.cc
+++ b/lily/group-interface.cc
@@ -55,6 +55,13 @@ Group_interface::set_interface ()
     }
 }
 
+Group_interface
+group (Score_element*s,String n)
+{
+  Group_interface gi (s,n);
+  return gi;
+}
+
 Group_interface
 group (Score_element*s)
 {
diff --git a/lily/include/directional-element.hh b/lily/include/directional-element.hh
deleted file mode 100644
index 139597f9cb..0000000000
--- a/lily/include/directional-element.hh
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/lily/include/group-interface.hh b/lily/include/group-interface.hh
index fc4a713f21..bf461a4052 100644
--- a/lily/include/group-interface.hh
+++ b/lily/include/group-interface.hh
@@ -29,6 +29,7 @@ public:
 };
 
 Group_interface group (Score_element*);
+Group_interface group (Score_element*, String);
 
 /*
   template<class T>
diff --git a/lily/include/request-iterator.hh b/lily/include/request-iterator.hh
new file mode 100644
index 0000000000..53a7a76070
--- /dev/null
+++ b/lily/include/request-iterator.hh
@@ -0,0 +1,24 @@
+/*   
+  request-iterator.hh -- declare Request_iterator
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#ifndef REQUEST_ITERATOR_HH
+#define REQUEST_ITERATOR_HH
+
+#include "music-iterator.hh"
+
+class Request_iterator : public Music_iterator
+{
+public:
+  Request_iterator ();
+protected:
+  virtual void do_process_and_next (Moment );
+};
+
+#endif /* REQUEST_ITERATOR_HH */
+
diff --git a/lily/include/side-position-interface.hh b/lily/include/side-position-interface.hh
index b3a37ae708..2a3ab87457 100644
--- a/lily/include/side-position-interface.hh
+++ b/lily/include/side-position-interface.hh
@@ -19,9 +19,10 @@ struct Side_position_interface
 public:
   Side_position_interface (Score_element const*);
   static Real side_position (Dimension_cache const *);
-  static Real self_alignment (Dimension_cache const *);
+  static Real aligned_on_self (Dimension_cache const *);
   static Real aligned_side (Dimension_cache const *);  
   static Real quantised_position (Dimension_cache const*);
+  static Real centered_on_parent (Dimension_cache const*);
   void set_axis (Axis);
   void set_quantised (Axis);
   Axis get_axis () const;
diff --git a/lily/include/tie-column.hh b/lily/include/tie-column.hh
index 11d17ed5ca..d4de3697df 100644
--- a/lily/include/tie-column.hh
+++ b/lily/include/tie-column.hh
@@ -17,7 +17,7 @@ class Tie_column : public Spanner
 {
 public:
   VIRTUAL_COPY_CONS (Score_element);
-  void add_tie (Score_element*);
+  void add_tie (Tie*);
   Tie_column ();
 protected:
   virtual void do_post_processing ();
diff --git a/lily/include/tie-engraver.hh b/lily/include/tie-engraver.hh
index bae7f6aa9a..fbd52deae6 100644
--- a/lily/include/tie-engraver.hh
+++ b/lily/include/tie-engraver.hh
@@ -9,54 +9,5 @@
 
 #ifndef CTIE_ENGRAVER_HH
 #define CTIE_ENGRAVER_HH
-
-#include "pqueue.hh"
-#include "engraver.hh"
-
-struct CHead_melodic_tuple {
-  Melodic_req *req_l_ ;
-  Note_head *head_l_;
-  Moment end_;
-  CHead_melodic_tuple ();
-  CHead_melodic_tuple (Note_head*, Melodic_req*, Moment);
-  static int pitch_compare (CHead_melodic_tuple const &, CHead_melodic_tuple const &);
-  static int time_compare (CHead_melodic_tuple const &, CHead_melodic_tuple const &);  
-};
-
-inline int compare (CHead_melodic_tuple const &a, CHead_melodic_tuple const &b)
-{
-  return CHead_melodic_tuple::time_compare (a,b);
-}
-
-
-/**
-   Manufacture ties.  Acknowledge noteheads, and put them into a
-   priority queue. If we have a Tie_req, connect the notes that finish
-   just at this time, and note that start at this time.
-
-   TODO: should share code with Beam_engraver, Extender_engraver?
- */
-class Tie_engraver : public Engraver
-{
-  PQueue<CHead_melodic_tuple> past_notes_pq_;
-  Tie_req *req_l_;
-  Array<CHead_melodic_tuple> now_heads_;
-  Array<CHead_melodic_tuple> stopped_heads_;
-  Link_array<Tie> tie_p_arr_;
-  
-  void set_melisma (bool);
-protected:
-  virtual void do_post_move_processing ();
-  virtual void do_pre_move_processing ();
-  virtual void acknowledge_element (Score_element_info);
-  virtual bool do_try_music (Music*);
-  virtual void do_process_requests ();
-  virtual void process_acknowledged ();
-
-public:
-  VIRTUAL_COPY_CONS(Translator);
-  Tie_engraver();
-};
-
 #endif /* CTIE_ENGRAVER_HH */
 
diff --git a/lily/include/tie.hh b/lily/include/tie.hh
index 16b3ff13e3..5e07334424 100644
--- a/lily/include/tie.hh
+++ b/lily/include/tie.hh
@@ -24,6 +24,9 @@ public:
   VIRTUAL_COPY_CONS(Score_element);
 
   Note_head* head (Direction) const;
+  Real position_f () const;
+  
+  virtual Direction get_default_dir() const;
 
 protected:
   virtual Molecule* do_brew_molecule_p () const;
@@ -35,7 +38,6 @@ protected:
 
   virtual void do_add_processing ();
   virtual void do_post_processing ();
-  virtual Direction get_default_dir() const;
 
   virtual Array<Rod> get_rods () const;
 
diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh
index 6601498d71..0f3fe7dd1a 100644
--- a/lily/include/translator-group.hh
+++ b/lily/include/translator-group.hh
@@ -23,13 +23,13 @@
 typedef void (Translator::*Method_pointer)(void);
 typedef void (Translator::*Const_method_pointer)(void) const; 
 
-/** Make some kind of #Element#s from Requests. Elements are made by
-  hierarchically grouped #Translator#s
+/** Make some kind of Elements from Requests. Elements are made by
+  hierarchically grouped Translators
   */
 class Translator_group : public virtual Translator {
   Array<String> consists_str_arr_;
-  Array<String> consists_end_str_arr_;
   Array<String> accepts_str_arr_;
+    Array<String> consists_end_str_arr_;
   Scheme_hash_table properties_dict_;
 
   int iterator_count_;
@@ -44,12 +44,12 @@ public:
   
 
   String id_str_;
+  void add_last_element (String s);
 
   VIRTUAL_COPY_CONS(Translator);
   
   void set_acceptor (String accepts, bool add);
   void set_element (String elt, bool add);  
-  void add_last_element (String elt);  
   
   Translator_group(Translator_group const &);
   Translator_group();
diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc
index 01e0a5dc5d..590271201c 100644
--- a/lily/music-iterator.cc
+++ b/lily/music-iterator.cc
@@ -30,6 +30,8 @@
 #include "lyric-combine-music-iterator.hh"
 #include "auto-change-music.hh"
 #include "auto-change-iterator.hh"
+#include "request.hh"
+#include "request-iterator.hh"
 
 void
 Music_iterator::do_print() const
@@ -147,10 +149,13 @@ Music_iterator::static_get_iterator_p (Music const *m)
       else
 	p = new Unfolded_repeat_iterator;
     }
+  else if (Request const * r = dynamic_cast<Request const* > (m))
+    {
+      p = new Request_iterator ;
+    }
   else
     assert (0);
 
-
   p->music_l_ = m;
   return p;
 }
diff --git a/lily/request-chord-iterator.cc b/lily/request-chord-iterator.cc
index dac3d2500c..65f3027077 100644
--- a/lily/request-chord-iterator.cc
+++ b/lily/request-chord-iterator.cc
@@ -30,7 +30,6 @@ Request_chord_iterator::elt_l () const
 Request_chord_iterator::Request_chord_iterator ()
 {
   last_b_ = false;
-  //  cursor_ = elt_l ()->music_p_list_p_->head_;
   cursor_ = 0;
 }
 
diff --git a/lily/request-iterator.cc b/lily/request-iterator.cc
new file mode 100644
index 0000000000..94d5e90dcc
--- /dev/null
+++ b/lily/request-iterator.cc
@@ -0,0 +1,29 @@
+/*   
+  request-iterator.cc --  implement 
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+#include "request-iterator.hh"
+#include "music.hh"
+
+Request_iterator::Request_iterator()
+{
+}
+
+
+void
+Request_iterator::do_process_and_next (Moment m)
+{
+  if (first_b_)
+    {
+      bool g= try_music (music_l_);
+      if (!g)
+	music_l_->warning (_f ("Junking request: `%s'", classname(music_l_)));
+
+      first_b_ = false;
+    }
+  Music_iterator::do_process_and_next (m);
+}
diff --git a/lily/score-element.cc b/lily/score-element.cc
index 768f07f7c7..42a7d083c2 100644
--- a/lily/score-element.cc
+++ b/lily/score-element.cc
@@ -222,14 +222,14 @@ Score_element::add_processing()
   if (get_elt_property ("self-alignment-X") != SCM_UNDEFINED
       && !dim_cache_[X_AXIS]->off_callback_l_)
     {
-      dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::self_alignment);
+      dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::aligned_on_self);
     }
   
   if (get_elt_property ("self-alignment-Y") != SCM_UNDEFINED
       && !dim_cache_[X_AXIS]->off_callback_l_)
       
     {
-      dim_cache_[Y_AXIS]->set_offset_callback (Side_position_interface::self_alignment);
+      dim_cache_[Y_AXIS]->set_offset_callback (Side_position_interface::aligned_on_self);
     }
 #endif
   
diff --git a/lily/side-position-interface.cc b/lily/side-position-interface.cc
index c0ae9afa3e..b60a6feb94 100644
--- a/lily/side-position-interface.cc
+++ b/lily/side-position-interface.cc
@@ -56,13 +56,14 @@ Side_position_interface::get_direction () const
   return DOWN;
 }
   
-/**
-   Callback that does the aligning.
+/*
+   Callback that does the aligning. Puts the element next to the support
  */
+
 Real
 Side_position_interface::side_position (Dimension_cache const * c)
 {
-  Score_element * me = dynamic_cast<Score_element*> (c->element_l ());
+  Score_element * me =  (c->element_l ());
 
   Interval dim;
   Axis  axis = c->axis ();
@@ -110,13 +111,16 @@ Side_position_interface::side_position (Dimension_cache const * c)
   return total_off;
 }
 
+/*
+  callback that centers the element on itself
+ */
 Real
-Side_position_interface::self_alignment (Dimension_cache const *c)
+Side_position_interface::aligned_on_self (Dimension_cache const *c)
 {
   String s ("self-alignment-");
   Axis ax = c->axis ();
   s +=  (ax == X_AXIS) ? "X" : "Y";
-  Score_element *elm = dynamic_cast<Score_element*> (c->element_l ());
+  Score_element *elm = c->element_l ();
   SCM align (elm->get_elt_property (s));
   if (isdir_b (align))
     {
@@ -132,7 +136,6 @@ Side_position_interface::self_alignment (Dimension_cache const *c)
     return 0.0;
 }
 
-
 Real
 directed_round (Real f, Direction d)
 {
@@ -142,10 +145,13 @@ directed_round (Real f, Direction d)
     return ceil (f);
 }
 
+/*
+  Callback that quantises in staff-spaces, rounding in the direction
+  of the elements "direction" elt property. */
 Real
 Side_position_interface::quantised_position (Dimension_cache const *c)
 {
-  Score_element * me = dynamic_cast<Score_element*> (c->element_l ());
+  Score_element * me =  (c->element_l ());
   Side_position_interface s(me);
   Direction d = s.get_direction ();
   Staff_symbol_referencer_interface si (me);
@@ -167,10 +173,13 @@ Side_position_interface::quantised_position (Dimension_cache const *c)
   return 0.0;
 }
 
+/*
+  Position next to support, taking into account my own dimensions and padding.
+ */
 Real
 Side_position_interface::aligned_side (Dimension_cache const *c)
 {
-  Score_element * me = dynamic_cast<Score_element*> (c->element_l ());
+  Score_element * me =  (c->element_l ());
   Side_position_interface s(me);
   Direction d = s.get_direction ();
   Axis ax = c->axis ();
@@ -189,6 +198,21 @@ Side_position_interface::aligned_side (Dimension_cache const *c)
   return o;
 }
 
+/*
+  Position centered on parent.
+ */
+Real
+Side_position_interface::centered_on_parent (Dimension_cache const *c)
+{
+
+  Score_element *me = c->element_l ();
+  Axis a = c->axis ();
+  Score_element *him = me->parent_l (a);
+
+  return him->extent (a).center ();  
+}
+
+
 void
 Side_position_interface::add_staff_support ()
 {
diff --git a/lily/tie-column.cc b/lily/tie-column.cc
index be2116eeeb..f23d218d93 100644
--- a/lily/tie-column.cc
+++ b/lily/tie-column.cc
@@ -9,24 +9,86 @@
 
 #include "tie-column.hh"
 #include "group-interface.hh"
+#include "tie.hh"
+#include "directional-element-interface.hh"
+#include "note-head.hh"
 
 Tie_column::Tie_column ()
 {
   set_elt_property ("ties", SCM_EOL);
+  set_empty (X_AXIS);
+  set_empty (Y_AXIS);  
+  set_elt_property ("transparent", SCM_BOOL_T);
 }
 
 void
-Tie_column::add_tie (Score_element *s)
+Tie_column::add_tie (Tie *s)
 {
-  group (s).add_element (s);
+  Group_interface g (this, "ties");
+  if (!g.count ())
+    {
+      set_bounds (LEFT, s->head (LEFT));
+      set_bounds (RIGHT, s->head (RIGHT));
+    }
+  
+  group (this, "ties").add_element (s);
   s->add_dependency (this);
 }
 
+
+int
+tie_compare (Tie* const & s1,
+	     Tie* const & s2)
+{
+  return sign (s1->position_f () - s2->position_f());
+}
+
+/*
+  See [Ross p. 138].
+
+
+  In normal chord cases, the outer ties point outwards, and the
+  direction of the rest is determined by their staff position.
+
+  Ross forgets about the tie that is *on* the middle staff line. We
+  assume it goes UP. (TODO: make this settable) */
 void
 Tie_column::set_directions ()
 {
-  Link_array<Score_element> s =
-    Group_interface__extract_elements (this, (Score_element*)0, "ties");
+  Link_array<Tie> s =
+    Group_interface__extract_elements (this, (Tie*)0, "ties");
+
+
+  Direction d = directional_element (this).get ();
+
+  if (d)
+    {
+      for (int i = s.size (); i--;)
+	directional_element (s[i]).set (d);
+      return;
+    }
+  
+  if (s.size () == 1)
+    {
+      directional_element (s[0]).set (s[0]->get_default_dir ());
+      return;
+    }
+  
+  s.sort (tie_compare);
+  directional_element (s[0]).set (DOWN);
+  s.del (0);
+  directional_element (s.pop ()).set (UP);
+
+  for (int i=s.size(); i--; )
+    {
+      Real p = s[i]->position_f ();
+      Direction d = (Direction) sign (p);
+      if (!d)
+	d = UP;
+
+      directional_element (s[i]).set (d);
+    }
+  
 }
 
 void
diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc
index 29f662c5f0..0090dbd9b5 100644
--- a/lily/tie-engraver.cc
+++ b/lily/tie-engraver.cc
@@ -13,10 +13,64 @@
 #include "musical-request.hh"
 #include "tie.hh"
 #include "translator-group.hh"
+#include "tie-column.hh"
+#include "pqueue.hh"
+#include "engraver.hh"
+
+struct CHead_melodic_tuple {
+  Melodic_req *req_l_ ;
+  Note_head *head_l_;
+  Moment end_;
+  CHead_melodic_tuple ();
+  CHead_melodic_tuple (Note_head*, Melodic_req*, Moment);
+  static int pitch_compare (CHead_melodic_tuple const &, CHead_melodic_tuple const &);
+  static int time_compare (CHead_melodic_tuple const &, CHead_melodic_tuple const &);  
+};
+
+inline int compare (CHead_melodic_tuple const &a, CHead_melodic_tuple const &b)
+{
+  return CHead_melodic_tuple::time_compare (a,b);
+}
+
+
+/**
+   Manufacture ties.  Acknowledge noteheads, and put them into a
+   priority queue. If we have a Tie_req, connect the notes that finish
+   just at this time, and note that start at this time.
+
+   TODO: should share code with Beam_engraver, Extender_engraver?
+ */
+class Tie_engraver : public Engraver
+{
+  PQueue<CHead_melodic_tuple> past_notes_pq_;
+  Tie_req *req_l_;
+  Array<CHead_melodic_tuple> now_heads_;
+  Array<CHead_melodic_tuple> stopped_heads_;
+  Link_array<Tie> tie_p_arr_;
+
+  Tie_column * tie_column_p_;
+  
+  void set_melisma (bool);
+  
+protected:
+  virtual void do_post_move_processing ();
+  virtual void do_pre_move_processing ();
+  virtual void acknowledge_element (Score_element_info);
+  virtual bool do_try_music (Music*);
+  virtual void do_process_requests ();
+  virtual void process_acknowledged ();
+
+public:
+  VIRTUAL_COPY_CONS(Translator);
+  Tie_engraver();
+};
+
+
 
 Tie_engraver::Tie_engraver()
 {
   req_l_ = 0;
+  tie_column_p_ = 0;
 }
 
 
@@ -145,7 +199,13 @@ Tie_engraver::process_acknowledged ()
 	{
 	  req_l_->warning (_ ("No ties were created!"));
 	}
-	  
+      else if (tie_p_arr_.size () > 1 && !tie_column_p_)
+	{
+	  tie_column_p_ = new Tie_column;
+	  for (int i = tie_p_arr_.size (); i--; )
+	    tie_column_p_->add_tie (tie_p_arr_ [i]);
+	  announce_element (Score_element_info (tie_column_p_, 0));
+	}
     }
 }
 
@@ -164,6 +224,11 @@ Tie_engraver::do_pre_move_processing ()
       typeset_element (tie_p_arr_[i]);
     }
   tie_p_arr_.clear ();
+  if (tie_column_p_)
+    {
+      typeset_element (tie_column_p_);
+      tie_column_p_ =0;
+    }
 }
 
 void
diff --git a/lily/tie.cc b/lily/tie.cc
index 6eb820b71f..989861002c 100644
--- a/lily/tie.cc
+++ b/lily/tie.cc
@@ -47,6 +47,14 @@ Tie::head (Direction d) const
   return dynamic_cast<Note_head*> (unsmob_element (c));  
 }
 
+Real
+Tie::position_f () const
+{
+  return head (LEFT)
+    ? staff_symbol_referencer (head (LEFT)).position_f ()
+    : staff_symbol_referencer (head (RIGHT)).position_f () ;  
+}
+
 
 /*
   ugh: direction of the Tie is more complicated.  See [Ross] p136 and further
@@ -80,8 +88,7 @@ Tie::do_add_processing()
   } while (flip(&d) != LEFT);
 
   index_set_cell (get_elt_property ("heads"), LEFT, new_head_drul[LEFT]->self_scm_ );
-  index_set_cell (get_elt_property ("heads"), RIGHT, new_head_drul[LEFT]->self_scm_ );
-
+  index_set_cell (get_elt_property ("heads"), RIGHT, new_head_drul[RIGHT]->self_scm_ );
 }
 
 void
@@ -141,9 +148,7 @@ Tie::do_post_processing()
    */
 
 
-  Real ypos = head (LEFT)
-    ? staff_symbol_referencer (head (LEFT)).position_f ()
-    : staff_symbol_referencer (head (RIGHT)).position_f () ;  
+  Real ypos = position_f ();
 
   Real y_f = half_staff_space * ypos; 
   int ypos_i = int (ypos);
@@ -243,7 +248,6 @@ Tie::get_curve () const
   return c;
 }
 
-
 Array<Offset>
 Tie::get_encompass_offset_arr () const
 {
diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm
index 0581974e2b..51583cc764 100644
--- a/make/out/lilypond.lsm
+++ b/make/out/lilypond.lsm
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.3.25
-Entered-date: 21FEB00
+Version: 1.3.26
+Entered-date: 23FEB00
 Description: 
 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.3.25.tar.gz 
+	1000k lilypond-1.3.26.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-	1000k lilypond-1.3.25.tar.gz 
+	1000k lilypond-1.3.26.tar.gz 
 Copying-policy: GPL
 End
diff --git a/make/out/lilypond.spec b/make/out/lilypond.spec
index ac2d335a1c..2d6bb4ef29 100644
--- a/make/out/lilypond.spec
+++ b/make/out/lilypond.spec
@@ -1,9 +1,9 @@
 Name: lilypond
-Version: 1.3.25
+Version: 1.3.26
 Release: 1
 Copyright: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.25.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.26.tar.gz
 Summary: A program for printing sheet music.
 URL: http://www.cs.uu.nl/~hanwen/lilypond
 # get Packager from (undocumented?) ~/.rpmmacros!
diff --git a/scm/generic-property.scm b/scm/generic-property.scm
index 6b7d312993..a13394ae09 100644
--- a/scm/generic-property.scm
+++ b/scm/generic-property.scm
@@ -98,6 +98,11 @@
 	       (list 'tieVerticalDirection dir? 'direction)
 	       (list 'verticalDirection dir? 'direction)
   )))
+(define generic-tie-column-properties
+  (cons "Tie_column" (list
+		      (list 'tieVerticalDirection dir? 'direction)
+		      (list 'verticalDirection dir? 'direction)
+  )))
 
 
 (define generic-note-column-properties
@@ -143,6 +148,7 @@
    generic-stem-properties
    generic-breathing-sign-properties
    generic-tie-properties
+   generic-tie-column-properties   
    generic-tuplet-spanner-properties
    generic-rest-properties
    generic-slur-properties
diff --git a/scm/lily.scm b/scm/lily.scm
index 74a4f2da4e..337387b0bf 100644
--- a/scm/lily.scm
+++ b/scm/lily.scm
@@ -93,7 +93,7 @@
 ;;
 ;;
 
-;; (Measured in interlines? -- jcn)
+;; (Measured in staff space)
 (define space-alist
  '(
    (("" "Clef_item") . (minimum-space 1.0))
-- 
2.39.5