From 03311c038c913d96eb7ed0a896e2c7d8f4815e17 Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Fri, 8 Sep 2000 11:52:19 +0200
Subject: [PATCH] release: 1.3.85

===========

* Updated INSTALL.texi

1.3.80.t
---
 CHANGES                                |  29 +++
 Documentation/user/mudela-book.tely    |  78 ++++---
 INSTALL.txt                            |  40 +++-
 VERSION                                |   4 +-
 input/bugs/notreich.ly                 |  32 +++
 input/bugs/steep.ly                    |  13 ++
 input/test/accidental-single-double.ly |   2 +-
 input/test/pushproperty.ly             |  26 ++-
 lily/include/lily-guile.hh             |   2 +
 lily/include/ly-smobs.icc              |   8 +-
 lily/include/music-output-def.hh       |   5 +-
 lily/include/smobs.hh                  |   1 +
 lily/include/translator-def.hh         |  56 +++++
 lily/include/translator-group.hh       |  15 --
 lily/include/translator.hh             |   7 +-
 lily/lexer.ll                          |   5 +-
 lily/lily-guile.cc                     |   4 +-
 lily/music-iterator.cc                 |  10 +-
 lily/music-output-def.cc               |  48 ++--
 lily/my-lily-lexer.cc                  |   2 +
 lily/parser.yy                         |  87 ++++----
 lily/property-iterator.cc              |   5 +-
 lily/staff-symbol-engraver.cc          |   2 +-
 lily/tie.cc                            |   7 +-
 lily/translator-ctors.cc               |   1 -
 lily/translator-def.cc                 | 292 +++++++++++++++++++++++++
 lily/translator-group-initializer.cc   |  95 --------
 lily/translator-group.cc               | 121 ++--------
 lily/translator.cc                     |  18 +-
 lilypond-mode.el                       |   2 +-
 ly/engraver.ly                         |  24 +-
 ly/performer.ly                        |   5 -
 make/lilypond.spec.in                  |   4 +-
 make/out/lilypond.lsm                  |   8 +-
 make/out/lilypond.spec                 |   8 +-
 scripts/mudela-book.py                 | 142 +++---------
 scripts/pmx2ly.py                      | 111 +++++++---
 stepmake/stepmake/help2man-rules.make  |   3 +-
 38 files changed, 788 insertions(+), 534 deletions(-)
 create mode 100644 input/bugs/notreich.ly
 create mode 100644 input/bugs/steep.ly
 create mode 100644 lily/include/translator-def.hh
 create mode 100644 lily/translator-def.cc
 delete mode 100644 lily/translator-group-initializer.cc

diff --git a/CHANGES b/CHANGES
index 032fa42e69..8e64408e4e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,37 @@
+
+* Separated definition and implementation of contexts (moved
+definition out of Translator_group into Translator_def)
+ 
+
+* pmx2ly.py fixes: now handles text at beginning of block correctly.
+
+* update .spec to include scripts. 
+
+* Changed syntax of \pushproperty:
+
+	\property Voice.basicXXXProperties \push #'foo = #bar
+	\property basicXXXProperties \pop #'foo
+
+	\translator {
+		basicXXXProperties \push #'foo = #bar
+		basicXXXProperties \pop #'foo
+	}
+
 1.3.84.jcn1
 ===========
 
 * Updated INSTALL.texi
 
+1.3.80.tca1
+===========
+* Added Documentation/user/mb-latex.tex, mudela-book+latex example
+  file and test case. Some work on Documentation/user/mudela-book.tely
+
+* mudela-book.py: any combination of \verb, \begin{verbatim}
+  @code and @example and mudela should work as expected. 
+
+* dropped [].extend that depend on python 1.5.2
+
 1.3.84
 ======
 
diff --git a/Documentation/user/mudela-book.tely b/Documentation/user/mudela-book.tely
index 65ef7fa736..7df11604a1 100644
--- a/Documentation/user/mudela-book.tely
+++ b/Documentation/user/mudela-book.tely
@@ -1,8 +1,7 @@
 \input texinfo @c -*-texinfo-*-
 @setfilename mudela-book.info
 @settitle mudela-book Manual
-
-
+@afourpaper
 @titlepage
 @title mudela-book Manual
 @subtitle Integrating mudela with La@TeX{} and TeXinfo
@@ -68,16 +67,21 @@ except that this permission notice may be stated in a
 translation approved by the Free Software Foundation.
 
 @end ifinfo
+@tex
+\def\preMudelaExample{\vspace{0.5cm}}
+@end tex
 
-
+@contents
 @node Top, , , (dir)
 @top
 
 
+
 @section Introduction
 
-[TODO: THIS MANUAL IS OUTDATED. FIXME.]
+[TODO: THIS MANUAL IS NOT FINISHED YET. FIXME.]
 
+@ignore
 Mudela-book is a script that process your La@TeX{} file and with great
 help from GNU LilyPond it translates blocks of mudela code it finds
 inside @code{mudela} environments to tex or eps graphics. It then
@@ -353,48 +357,48 @@ defined to nothing by default, and the user can redefine them
 to whatever he wants.
 
 @code{\begin} takes the following options:
+@end ignore
 
-@table @samp
-@item eps
-    the music is created as eps graphics that can be inserted in 
-    the middle of a text line, not only as a separate paragraph
-@item verbatim
-    CONTENTS is copied into the TeX source enclosed in a verbatim block.
-@item 11pt, 13pt, 16pt, 20pt, 26pt
-    set the fontsize to use for the music
-@item singleline
-  linewidth = -1.
-@item multiline
-  linewidth = textwidth
-@item fragment
-@item nonfragment
-    Override mudela-book autodetection of what type of code is in the
-    mudela block, voice contents or complete code.
-@end table
 
+@subsection Command line options
 
 @table @samp
 
-@item --default-mudela-fontsize=??pt
+@item -f, --format=
+    Specify the document type to process, @code{latex} or @code{texi}.
+    @file{mudela-book} usually figure out this automatically.
+@item --default-music-fontsize=??pt
     Set the fontsize to use for mudela if no fontsize is given
     as option.
-@item --force-mudela-fontsize=??pt
+@item --force-music-fontsize=??pt
     Force all mudela to use this fontsize, overriding options
     given to \begin@{mudela@}
+@item -I DIR, --include=DIR
+    include path
+@item -M, --dependencies
+        Write dependencies to out-www/filename.dep
+@item --dep-prefix=PREF
+	prepend PREF before each -M dependency
+@item -n, --no-lily
+	don't run lilypond
+@item --no-pictures
+	don't generate pictures
+@item --read-lys
+	don't write ly files. This way you can do
+	@example
+	mudela-book file.tely
+	convert-mudela
+	mudela-book --read-lys
+	@end example
 @item --outname=FILE
     The name of La@TeX{} file to output. If this option  is not given,
-the output name derived from the input name.
-@item --out-www=DIRECTORY
-    The name of the directory to output lilypond output and input to.
-    This must be a name; the subdirectory will be created in the cwd. [FIXME]
+    the output name derived from the input name.
+@item --outdir=
+	where to place generated files
+@item --version
+	print version information
 @item --help
 	Print a short help message
-@item --dependencies
-        Write dependencies to out-www/filename.dep
-@item --force-verbatim
-	Make all mudela verbatim.
-@item --initfile=FILE
-        read command definitions from @file{FILE}
 @end table
 
 
@@ -410,12 +414,16 @@ The La@TeX{} \includeonly@{...@} command is ignored.
 
 Ignores almost all La@TeX{} commands that changes margins and linewidths.
 
+La@TeX{} comments can confuse mudela-book:
+@example
+% this music will be displayed: \mudela@{c d e@}
+@end example
+
 @section Authors
 
 @email{hanwen@@cs.uu.nl, Han-Wen Nienhuys}, @uref{http://www.cs.uu.nl/people/hanwen}
 
-@email{tomato@@xoommail.com, Tom Cato Amundsen}
-
+@email{tca@@gnu.org, Tom Cato Amundsen}
 
 @bye
 
diff --git a/INSTALL.txt b/INSTALL.txt
index 73a3a997dd..db0ba70a3c 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -270,9 +270,9 @@ following for the normal build,
    and for the profiling version, I specify a different configuration.
 
 
-           ./configure --prefix=~ --enable-profiling --enable-config=optprof --enable-optimise --disable-checking
-           make config=optprof
-           make config=optprof install
+           ./configure --prefix=~ --enable-profiling --enable-config=prof --enable-optimise --disable-checking
+           make config=prof
+           make config=prof install
 
 Installing
 ==========
@@ -316,14 +316,44 @@ addition to the those needed for running:
 
    * texinfo
 
+   * tetex-devel
+
 Debian GNU/linux
 ================
 
    A Debian package is also available; see
 http://packages.debian.org/lilypond
 (http://packages.debian.org/lilypond) or contact Anthony Fok
-<foka@debian.org> for more information.  The build scripts are in the
-subdirectory `debian/'.
+<foka@debian.org> for more information.
+
+   The build scripts are in the subdirectory `debian/'; you can make
+the .deb by doing
+
+
+     	tar xzf lilypond-x.y.z.tar.gz
+     	cd lilypond-x.y.z
+     	dpkg-buildpackage
+     	dpkg -i ../lilypond_x.y.z*deb
+
+   For compilation on a Debian GNU/Linux system you need these packages,
+in addition to the those needed for running:
+   * libc6-dev
+
+   * libstdc++<your-libstdc++-version-here>-dev
+
+   * libguile<your-libguile-version-here>-dev
+
+   * flex
+
+   * bison
+
+   * gettext
+
+   * texinfo
+
+   * tetex-dev
+
+   * debhelper
 
 Windows NT/95
 =============
diff --git a/VERSION b/VERSION
index 59d122f26f..90149d788b 100644
--- a/VERSION
+++ b/VERSION
@@ -1,8 +1,8 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
-PATCH_LEVEL=84
-MY_PATCH_LEVEL=jcn1
+PATCH_LEVEL=85
+MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff --git a/input/bugs/notreich.ly b/input/bugs/notreich.ly
new file mode 100644
index 0000000000..cef3c9c8dd
--- /dev/null
+++ b/input/bugs/notreich.ly
@@ -0,0 +1,32 @@
+
+% GENERATED AUTOMATICALLY
+
+\header {
+  title = "Not Clapping Music" ;
+  instrument = "For four hands";
+  composer = "Not Steve Reich";
+  year = "1972";
+}
+
+
+beaming = \notes \repeat unfold 13 {  \repeat unfold 3 { [ s2 ] } \bar ":|:"; }
+
+\score {
+	\notes <
+%	        \property Score.midiInstrument = "woodblock"
+	        \property Score.midiInstrument = "melodic tom"
+		\context RhythmicStaff = SA 
+		  \context Voice = VA <
+		  \time 12/8 ;
+		       { c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 r }  \beaming
+			s8^"No accents whatsoever"
+			{ s1.  \mark "8$\\times$"; }
+
+
+		  > 
+		\context RhythmicStaff = SB
+		   \context Voice = VA < { c8 c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 r c8 r c8 c8 r c8 c8 r c8 c8 c8 c8 r c8 c8 r c8 c8 r c8 c8 c8 r r c8 c8 r c8 c8 r c8 c8 c8 r c8 c8 c8 r c8 c8 r c8 c8 c8 r c8 r c8 r c8 c8 r c8 c8 c8 r c8 r c8 r c8 c8 r c8 c8 c8 r c8 r c8 c8 c8 c8 r c8 c8 c8 r c8 r c8 c8 r c8 r c8 c8 c8 r c8 r c8 c8 r c8 r c8 c8 c8 r c8 r c8 c8 r c8 c8 c8 c8 c8 r c8 r c8 c8 r c8 c8 r }  \beaming >
+	>
+	\paper{ \translator { \ScoreContext \consists Mark_engraver; }}
+	\midi {\tempo 4 = 130;}
+	} 
diff --git a/input/bugs/steep.ly b/input/bugs/steep.ly
new file mode 100644
index 0000000000..ae7d10cac2
--- /dev/null
+++ b/input/bugs/steep.ly
@@ -0,0 +1,13 @@
+
+
+\score{
+	\notes\relative c''{
+		a'( a a [a8...] b,32\break
+		c4 \clef bass; c,,, c )c
+	}
+	\paper{
+		indent=0.0\mm;
+		linewidth=40.0\mm;
+	}
+}
+
diff --git a/input/test/accidental-single-double.ly b/input/test/accidental-single-double.ly
index c2d73e131a..a4769eea58 100644
--- a/input/test/accidental-single-double.ly
+++ b/input/test/accidental-single-double.ly
@@ -14,7 +14,7 @@ gis g ges g |
 
 \score { < \context Staff \thenotes
 	\context NoteNames  {
-		\pushproperty #'basicNoteNameProperties #'no-spacing-rods ##f 
+		\property NoteNames.basicNoteNameProperties \push  #'no-spacing-rods  = ##f 
 		\thenotes
 	}
 	>
diff --git a/input/test/pushproperty.ly b/input/test/pushproperty.ly
index 0ab097c1a3..163ebc395d 100644
--- a/input/test/pushproperty.ly
+++ b/input/test/pushproperty.ly
@@ -27,10 +27,6 @@ setting stem directions by doing.
 
 (#-1 if you want down).  
 
-Generally \pushproperty and \popproperty take precedence over
-\property, so in this example \property stemVerticalDirection will not
-work as long as you did a \pushproperty on basicStemProperties
-
 A modest amount of memory is involved each time you do a
 \pushproperty. If you do \popproperty in the right order (reversed
 from \pushproperty), then \popproperty doesn't cost memory.
@@ -49,8 +45,7 @@ Incorrect (\popproperty costs memory):
 	\popproperty #'(  ... ) #'symbolA 
 	\popproperty #'(  ... ) #'symbolB 
 
-the syntax isn't likely to stay, so it is advisable to
-use identifiers, eg.
+You can use identifiers, eg.
 
     slursUp = \context Voice \pushproperty '(basicSlurProperties)
 	    #'direction  #1
@@ -61,20 +56,27 @@ use identifiers, eg.
 \score { \notes
 \relative c' {
 	c4-.(
-	\context Voice \pushproperty #'(basicDotsProperties basicStemProperties
-	basicNoteColumnProperties basicScriptProperties basicTextProperties) #'direction #-1
+	\property Voice.basicDotsProperties \push #'direction =  #-1
+	\property Voice.basicStemProperties \push #'direction =  #-1
+	\property Voice.noteColumnProperties \push #'direction =  #-1
+	\property Voice.basicStemProperties \push #'direction =  #-1		
+	
 	) c4-. (
 	) c4-. (	
-	\context Voice \pushproperty #'basicSlurProperties #'direction #-1
-	) c4-. ( \context Voice  \popproperty #'(basicDotsProperties basicStemProperties
-		basicScriptProperties basicTextProperties) #'direction
+	 \property Voice.basicSlurProperties \push #'direction =  #-1
+	) c4-. (
+
+	\property basicDotsProperties \pop  #'direction
+	\property basicStemProperties \pop #'direction
+	\property basicScriptProperties \pop #'direction
+	\property basicTextProperties \pop #'direction
 
 	 ) c4-.  () c4-. 
 }
 
 \paper {
 \translator { \VoiceContext
-	\pushproperty #'basicNoteHeadProperties #'font-size #-2
+	basicNoteHeadProperties \push #'font-size =  #-2
 }
 }
 }
diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh
index fed4a8af55..36ed954f41 100644
--- a/lily/include/lily-guile.hh
+++ b/lily/include/lily-guile.hh
@@ -51,7 +51,9 @@ SCM ly_type (SCM);
 /*
   display and print newline.
  */
+extern "C" { 
 void ly_display_scm (SCM s);
+}
 
 #include "array.hh"
 
diff --git a/lily/include/ly-smobs.icc b/lily/include/ly-smobs.icc
index b17bd314f1..0bcb9d2e8d 100644
--- a/lily/include/ly-smobs.icc
+++ b/lily/include/ly-smobs.icc
@@ -67,6 +67,13 @@ ADD_SCM_INIT_FUNC(CL, CL::init_smobs)
 IMPLEMENT_SIMPLE_SMOBS(CL)							\
 SCM										\
 CL::smobify_self ()								\
+{										\
+  SCM s =   unprotected_smobify_self ();\
+  scm_protect_object (s);\
+  return s;\
+}\
+SCM										\
+CL::unprotected_smobify_self ()								\
 {										\
   /*										\
     This is local. We don't assign to self_scm_ directly, to assure		\
@@ -82,7 +89,6 @@ CL::smobify_self ()								\
   SCM_SETCDR (s, SCM_PACK(this));						\
   self_scm_ = s;								\
  scm_done_malloc(sizeof(CL));							\
-  scm_protect_object (s);							\
   return s;									\
 }
 
diff --git a/lily/include/music-output-def.hh b/lily/include/music-output-def.hh
index eb20e22d11..a5c5c8d152 100644
--- a/lily/include/music-output-def.hh
+++ b/lily/include/music-output-def.hh
@@ -12,6 +12,7 @@
 
 #include "string.hh"
 #include "lily-proto.hh"
+#include "lily-guile.hh"
 #include "virtual-methods.hh"
 
 /**
@@ -33,8 +34,8 @@ public:
   Global_translator *get_global_translator_p ();
   Translator_group *get_group_translator_p (String type) const;
   String get_default_output () const;
-  void assign_translator (Translator_group*);
-  Translator * find_translator_l (String) const;
+  void assign_translator (SCM transdef);
+  SCM find_translator_l (SCM name) const;
 };
 
 #endif // Music_output_DEF_HH
diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh
index edd1f2e60c..c881c05ad6 100644
--- a/lily/include/smobs.hh
+++ b/lily/include/smobs.hh
@@ -119,6 +119,7 @@ private:
 	DECLARE_SIMPLE_SMOBS(CL,dammy) \
 protected:\
 	virtual ~CL();\
+	SCM unprotected_smobify_self ();\
 private: \
 	SCM smobify_self ();					\
 	SCM self_scm_; \
diff --git a/lily/include/translator-def.hh b/lily/include/translator-def.hh
new file mode 100644
index 0000000000..c985222a40
--- /dev/null
+++ b/lily/include/translator-def.hh
@@ -0,0 +1,56 @@
+/*   
+  translator-def.hh -- declare Translator_def
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#ifndef TRANSLATOR_DEF_HH
+#define TRANSLATOR_DEF_HH
+
+#include "lily-proto.hh"
+#include "smobs.hh"
+#include "input.hh"
+
+struct Translator_def : public Input
+{
+  SCM consists_name_list_;
+  SCM end_consists_name_list_;
+  SCM accepts_name_list_;
+  SCM property_ops_;
+  SCM type_name_;
+  SCM translator_group_type_;
+
+  SCM modify_definition (SCM, SCM, bool);
+  
+  void set_acceptor (SCM accepts, bool add);
+  void add_element (SCM name);
+  void remove_element (SCM name);
+  void add_last_element (SCM name);
+
+  void add_push_property (SCM,SCM,SCM);
+  void add_pop_property (SCM,SCM);
+  void add_property_assign (SCM, SCM);
+  Link_array<Translator_def> path_to_acceptable_translator (SCM type_str, Music_output_def* odef) const;
+  Translator_group * instantiate (Music_output_def*);
+
+  static SCM make_scm () ;
+  static void apply_pushpop_property (Translator_group*, SCM syms, SCM eprop, SCM val);
+
+  SCM clone_scm ()const;
+  DECLARE_SMOBS(Translator_def,foo);
+private:
+
+  Translator_def ();
+  Translator_def (Translator_def const&);
+
+
+};
+
+Translator_def* unsmob_translator_def (SCM);
+
+
+#endif /* TRANSLATOR_DEF_HH */
+
diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh
index 4701c48bbb..507ff124b4 100644
--- a/lily/include/translator-group.hh
+++ b/lily/include/translator-group.hh
@@ -22,21 +22,6 @@ typedef void (Translator::*Method_pointer)(void);
 
 class Scheme_hash_table;
 
-/*
-  should make a struct out of this, and move SCM list stuff in here.
- */
-struct Translator_group_initializer {
-  static SCM modify_definition (SCM, SCM, bool);
-
-  static void set_acceptor (Translator*,SCM accepts, bool add);
-  static void add_element (Translator*,SCM name);
-  static void remove_element (Translator*,SCM name);
-  static void add_last_element (Translator*,SCM name);
-  static void apply_pushpop_property (Translator*trans, SCM syms, SCM eprop, SCM val);
-  static void add_push_property (Translator*, SCM,SCM,SCM);
-  static void add_pop_property (Translator*, SCM,SCM);  
-  
-};
 
 /** Make some kind of Elements from Requests. Elements are made by
   hierarchically grouped Translators
diff --git a/lily/include/translator.hh b/lily/include/translator.hh
index 2cca991105..74a46a1fd2 100644
--- a/lily/include/translator.hh
+++ b/lily/include/translator.hh
@@ -68,15 +68,12 @@ public:
   /*
     ugh: bubbled up from Translator_group. 
    */
-  SCM consists_name_list_;
-  SCM end_consists_name_list_;
-  SCM accepts_name_list_;
   SCM simple_trans_list_;
   SCM trans_group_list_;
+  SCM definition_;
+  
   SCM properties_scm_;
-  SCM property_pushes_;
   DECLARE_SMOBS(Translator, dummy);
-
 public:
   /*
     UGH. Clean this up.
diff --git a/lily/lexer.ll b/lily/lexer.ll
index 09378ba961..dfbdfd9a36 100644
--- a/lily/lexer.ll
+++ b/lily/lexer.ll
@@ -39,7 +39,8 @@
 #include "identifier.hh"
 #include "version.hh"
 #include "mudela-version.hh"
-#include "translator-group.hh"
+#include "translator-def.hh"
+
 void strip_trailing_white (String&);
 void strip_leading_white (String&);
 
@@ -477,7 +478,7 @@ My_lily_lexer::scan_escaped_word (String str)
 	} else if (gh_number_p (sid)) {
 		yylval.scm = sid;
 		return NUMBER_IDENTIFIER;
-	} else if (Translator* tr = unsmob_translator (sid)) {
+	} else if (Translator_def* tr = unsmob_translator_def (sid)) {
 		yylval.scm = sid;
 		return TRANSLATOR_IDENTIFIER;
 	} else if (Music * mus =unsmob_music (sid)) {
diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc
index 325517061f..6f6b93e280 100644
--- a/lily/lily-guile.cc
+++ b/lily/lily-guile.cc
@@ -147,13 +147,15 @@ read_lily_scm_file (String fn)
   gh_eval_str ((char *) gulp_file_to_string (fn).ch_C());
 }
 
-
+extern "C" {
+  // maybe gdb 5.0 becomes quicker if it doesn't do fancy C++ typing?
 void
 ly_display_scm (SCM s)
 {
   gh_display (s);
   gh_newline ();
 }
+};
 
 String
 ly_scm2string (SCM s)
diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc
index bfa597527b..b1697e199e 100644
--- a/lily/music-iterator.cc
+++ b/lily/music-iterator.cc
@@ -134,19 +134,19 @@ Music_iterator::static_get_iterator_p (Music  *m)
     p = new Request_chord_iterator;
   else if (dynamic_cast<Lyric_combine_music *> (m))
     p = new Lyric_combine_music_iterator;
-  else if (dynamic_cast<Simultaneous_music   *> (m)) 
+  else if (dynamic_cast<Simultaneous_music *> (m)) 
     p =  new Simultaneous_music_iterator;
-  else if (dynamic_cast<Sequential_music   *> (m)) 
+  else if (dynamic_cast<Sequential_music *> (m)) 
     p =  new Sequential_music_iterator;
-  else if (dynamic_cast<Translation_property   *> (m))
+  else if (dynamic_cast<Translation_property *> (m))
     p = new Property_iterator;
-  else if (dynamic_cast<Change_translator   *> (m))
+  else if (dynamic_cast<Change_translator *> (m))
     p = new Change_iterator;
   else if (dynamic_cast<Push_translation_property*>(m))
     p = new Push_property_iterator;
   else if (dynamic_cast<Pop_translation_property*>(m))
     p = new Pop_property_iterator;
-  else if (dynamic_cast<Time_scaled_music   *> (m))
+  else if (dynamic_cast<Time_scaled_music *> (m))
     p = new Time_scaled_music_iterator;
   else if (dynamic_cast<Grace_music *> (m))
     p = new Grace_iterator;
diff --git a/lily/music-output-def.cc b/lily/music-output-def.cc
index a0107291a5..438ea4cca6 100644
--- a/lily/music-output-def.cc
+++ b/lily/music-output-def.cc
@@ -11,7 +11,7 @@
 #include "debug.hh"
 #include "music-output-def.hh"
 #include "global-translator.hh"
-
+#include "translator-def.hh"
 #include "identifier.hh"
 #include "main.hh"
 #include "lily-guile.hh"
@@ -43,48 +43,38 @@ Music_output_def::Music_output_def (Music_output_def const &s)
 }
 
 void
-Music_output_def::assign_translator (Translator_group*tp)
+Music_output_def::assign_translator (SCM transdef)
 {
-  String s =tp->type_str_;
-  if (s.empty_b ())
-    {
-      tp->warning (_("Interpretation context with empty type"));
-    }
-
-  SCM tr = tp->self_scm ();
-  scm_unprotect_object (tr);
-  translator_p_dict_p_->set (s, tr);
+  Translator_def *tp = unsmob_translator_def (transdef);
+  assert (tp);
+
+  String s = ly_scm2string (tp->type_name_);
+  translator_p_dict_p_->set (s, transdef);
 }
 
-Translator*
-Music_output_def::find_translator_l (String name) const
+SCM
+Music_output_def::find_translator_l (SCM name) const
 {
-  if (translator_p_dict_p_->elem_b (name))
-    return unsmob_translator (translator_p_dict_p_->scm_elem (name));
-
-  map<String, Translator*>::const_iterator ki
-    =global_translator_dict_p->find (name);
-
-  if (ki != global_translator_dict_p->end ())
-    return (*ki).second ;
+  String s = ly_scm2string (name);
+  if (translator_p_dict_p_->elem_b (s))
+    return translator_p_dict_p_->scm_elem (s);
 
-  return 0;
+  return SCM_EOL;
 }
 
 
 Global_translator *
 Music_output_def::get_global_translator_p () 
 {
-  Translator * t = find_translator_l ("Score");
+  Translator_def * t = unsmob_translator_def (find_translator_l (gh_str02scm ("Score")));
   if (!t)
     error (_f ("can't find `%s' context", "Score"));
-  t = t->clone ();
 
-  t->output_def_l_ = this;
-  Global_translator *g = dynamic_cast <Global_translator *> (t);
-  t->add_processing ();
+  Translator_group * tg = t->instantiate (this);
+  
+  tg->add_processing ();
   
-  return g;
+  return dynamic_cast <Global_translator *> (tg);
 }
 
 void
@@ -98,8 +88,6 @@ Music_output_def::get_default_output () const
   if (safe_global_b || !scope_p_->elem_b ("output"))
     return "";
   SCM s =  scope_p_->scm_elem ("output");
-
-  
   
   return gh_string_p (s) ? ly_scm2string (s) : String ("");
 }
diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc
index 6fe78ea1cc..a3dc6043ac 100644
--- a/lily/my-lily-lexer.cc
+++ b/lily/my-lily-lexer.cc
@@ -60,6 +60,8 @@ static Keyword_ent the_key_tab[]={
   {"outputproperty", OUTPUTPROPERTY},
   {"pushproperty", PUSHPROPERTY},
   {"popproperty", POPPROPERTY},
+  {"push", PUSH},
+  {"pop", POP},
   {"partial", PARTIAL},
   {"paper", PAPER},
   {"penalty", PENALTY},
diff --git a/lily/parser.yy b/lily/parser.yy
index 8db7014cdf..13fd818479 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -10,6 +10,7 @@
 */
 
 #include <iostream.h>
+#include "translator-def.hh"
 #include "lily-guile.hh"
 #include "translation-property.hh"
 #include "lookup.hh"
@@ -26,7 +27,6 @@
 #include "musical-request.hh"
 #include "my-lily-parser.hh"
 #include "context-specced-music.hh"
-#include "translator-group.hh"
 #include "score.hh"
 #include "music-list.hh"
 #include "change-translator.hh"
@@ -106,7 +106,6 @@ of the parse stack onto the heap. */
     SCM scm;
 
     Tempo_req *tempo;
-    Translator_group* trans;
     int i;
 }
 %{
@@ -166,6 +165,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %token PENALTY
 %token PROPERTY
 %token PUSHPROPERTY POPPROPERTY
+%token PUSH POP 
 %token PT_T
 %token RELATIVE
 %token REMOVE
@@ -253,7 +253,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <scm>	string bare_number number_expression
 %type <score>	score_block score_body
 
-%type <trans>	translator_spec_block translator_spec_body
+%type <scm>	translator_spec_block translator_spec_body
 %type <tempo> 	tempo_request
 %type <scm> notenames_body notenames_block chordmodifiers_block
 %type <scm>	script_abbreviation
@@ -386,8 +386,7 @@ identifier_init:
 		$$ = (new Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER))->self_scm();
 	}
 	| translator_spec_block {
-		$$ = $1->self_scm ();
-		scm_unprotect_object ($$);
+		$$ = $1;
 	}
 	| Music  {
 		$$ = $1->self_scm ();
@@ -420,25 +419,25 @@ translator_spec_block:
 
 translator_spec_body:
 	TRANSLATOR_IDENTIFIER	{
-		SCM trs = $1;
-		Translator*tr = unsmob_translator (trs);
-		$$ = dynamic_cast<Translator_group*> (tr->clone ());
-		$$-> set_spot (THIS->here_input ());
+		$$ = unsmob_translator_def ($1)->clone_scm ();
+		unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
 	}
 	| TYPE STRING semicolon	{
-		Translator* t = get_translator_l (ly_scm2string ($2));
-		Translator_group * tg = dynamic_cast<Translator_group*> (t);
-
-		if (!tg)
-			THIS->parser_error (_("Need a translator group for a context"));
-		
-		tg = dynamic_cast<Translator_group*> (t->clone ());
-		tg->set_spot (THIS->here_input ());
-		$$ = tg;
+		$$ = Translator_def::make_scm ();
+		Translator_def*td =  unsmob_translator_def ($$);
+		td->translator_group_type_ = $2;
+		td->set_spot (THIS->here_input ());
 	}
 	| translator_spec_body STRING '=' embedded_scm			{
-		Translator_group* tg = $$;
-		tg->set_property (ly_scm2string ($2), $4);
+		unsmob_translator_def ($$)->add_property_assign ($2, $4);
+	}
+	| translator_spec_body STRING PUSH embedded_scm '=' embedded_scm {
+		unsmob_translator_def ($$)
+			->add_push_property (scm_string_to_symbol ($2), $4, $6);
+	}
+	| translator_spec_body STRING POP embedded_scm  {
+	  unsmob_translator_def($$)->add_pop_property (
+		scm_string_to_symbol ($2), $4);
 	}
 	| translator_spec_body STRING '=' identifier_init semicolon	{ 
 		SCM v = gh_int2scm (0);
@@ -448,35 +447,25 @@ translator_spec_body:
 			THIS->parser_error (_("Wrong type for property value"));
 
 		/* ugh*/
-		Translator_group* tg = dynamic_cast<Translator_group*> ($$);
-		
-		tg->set_property (ly_scm2string ($2), v);
-	}
-	| translator_spec_body PUSHPROPERTY
-				embedded_scm embedded_scm embedded_scm {
-		Translator_group_initializer::add_push_property ($$, $3, $4, $5);
-	}
-	| translator_spec_body POPPROPERTY
-		embedded_scm embedded_scm  {
-		Translator_group_initializer::add_pop_property ($$, $3, $4);
+		unsmob_translator_def($$)->add_property_assign ($2, v);
 	}
 	| translator_spec_body NAME STRING semicolon {
-		$$->type_str_ = ly_scm2string ($3);
+		unsmob_translator_def ($$)->type_name_ = $3;
 	}
 	| translator_spec_body CONSISTS STRING semicolon {
-		Translator_group_initializer::add_element ($$, $3);
+		unsmob_translator_def ($$)->add_element ($3);
 	}
 	| translator_spec_body CONSISTSEND STRING semicolon {
-		Translator_group_initializer::add_last_element ($$, $3);
+		unsmob_translator_def ($$)->add_last_element ( $3);
 	}
 	| translator_spec_body ACCEPTS STRING semicolon {
-		Translator_group_initializer::set_acceptor ($$, $3,true);
+		unsmob_translator_def ($$)->set_acceptor ($3,true);
 	}
 	| translator_spec_body DENIES STRING semicolon {
-		Translator_group_initializer::set_acceptor ($$, $3,false);
+		unsmob_translator_def ($$)->set_acceptor ($3,false);
 	}
 	| translator_spec_body REMOVE STRING semicolon {
-		Translator_group_initializer::remove_element ($$, $3);
+		unsmob_translator_def ($$)->remove_element ($3);
 	}
 	;
 
@@ -569,7 +558,7 @@ music_output_def_body:
 
 	}
 	| music_output_def_body translator_spec_block	{
-		$$-> assign_translator ($2);
+		$$->assign_translator ($2);
 	}
 	| music_output_def_body tempo_request semicolon {
 		/*
@@ -693,17 +682,18 @@ Simple_music:
 	}
 	| MUSIC_IDENTIFIER { $$ = unsmob_music ($1)->clone (); }
 	| property_def
-	| PUSHPROPERTY embedded_scm embedded_scm embedded_scm {
+/*	| PUSHPROPERTY embedded_scm embedded_scm embedded_scm {
 		$$ = new Push_translation_property;
 		$$->set_mus_property ("symbols", $2);
 		$$->set_mus_property ("element-property", $3);
 		$$->set_mus_property ("element-value", $4);
 	}
-	| POPPROPERTY  embedded_scm embedded_scm {
+	| POPPROPERTY embedded_scm embedded_scm {
 		$$ = new Pop_translation_property;
 		$$->set_mus_property ("symbols", $2);
 		$$->set_mus_property ("element-property", $3);
 	}
+*/
 	| translator_change
 	| Simple_music '*' bare_unsigned '/' bare_unsigned 	{
 		$$ = $1;
@@ -834,6 +824,23 @@ property_def:
 
 		csm-> translator_type_str_ = ly_scm2string ($2);
 	}
+	| PROPERTY STRING '.' STRING PUSH embedded_scm '=' embedded_scm {
+		Push_translation_property *t = new Push_translation_property;
+
+		t->set_mus_property ("symbols", scm_string_to_symbol ($4));
+		t->set_mus_property ("element-property", $6);
+		t->set_mus_property ("element-value", $8);
+		Context_specced_music *csm = new Context_specced_music (t);
+		$$ = csm;
+		$$->set_spot (THIS->here_input ());
+
+		csm-> translator_type_str_ = ly_scm2string ($2);
+	}
+	| PROPERTY STRING POP embedded_scm {
+		$$ = new Pop_translation_property;
+		$$->set_mus_property ("symbols", scm_string_to_symbol ($2));
+		$$->set_mus_property ("element-property", $4);
+	}
 	;
 
 scalar:
diff --git a/lily/property-iterator.cc b/lily/property-iterator.cc
index 41b0ed5406..2f44683094 100644
--- a/lily/property-iterator.cc
+++ b/lily/property-iterator.cc
@@ -8,6 +8,7 @@
 
 #include "property-iterator.hh"
 #include "translation-property.hh"
+#include "translator-def.hh"
 #include "translator-group.hh"
 
 /**
@@ -31,7 +32,7 @@ Push_property_iterator::do_process_and_next (Moment m)
   SCM eprop = music_l_->get_mus_property ("element-property");
   SCM val = music_l_->get_mus_property ("element-value");
 
-  Translator_group_initializer::apply_pushpop_property (report_to_l (), syms,eprop, val);
+  Translator_def::apply_pushpop_property (report_to_l (), syms, eprop, val);
   
   Music_iterator::do_process_and_next (m);
 }
@@ -41,7 +42,7 @@ Pop_property_iterator::do_process_and_next (Moment m)
 {
   SCM syms = music_l_->get_mus_property ("symbols");
   SCM eprop = music_l_->get_mus_property ("element-property");
-  Translator_group_initializer::apply_pushpop_property (report_to_l (), syms, eprop, SCM_UNDEFINED);
+  Translator_def::apply_pushpop_property (report_to_l (), syms, eprop, SCM_UNDEFINED);
   
   Music_iterator::do_process_and_next (m);
 }
diff --git a/lily/staff-symbol-engraver.cc b/lily/staff-symbol-engraver.cc
index 410cbac927..2917e16a45 100644
--- a/lily/staff-symbol-engraver.cc
+++ b/lily/staff-symbol-engraver.cc
@@ -44,7 +44,7 @@ Staff_symbol_engraver::Staff_symbol_engraver()
 void
 Staff_symbol_engraver::do_creation_processing()
 {
-  span_p_ = new Spanner (get_property ("staffSymbolBasicProperties"));
+  span_p_ = new Spanner (get_property ("basicStaffSymbolProperties"));
   
   span_p_->set_bound(LEFT, unsmob_element (get_property ("currentCommandColumn")));
 
diff --git a/lily/tie.cc b/lily/tie.cc
index 0ce6fbd983..d40b0c3369 100644
--- a/lily/tie.cc
+++ b/lily/tie.cc
@@ -76,8 +76,12 @@ Tie::position_f (Score_element*me)
 
 
 /*
+  Default:  Put the tie oppositie of the stem [Wanske p231]
+
+  In case of chords: Tie_column takes over
+  
   The direction of the Tie is more complicated (See [Ross] p136 and
-  further), the case of multiple ties is handled by Tie_column.
+  further).
 */
 Direction
 Tie::get_default_dir (Score_element*me) 
@@ -85,7 +89,6 @@ Tie::get_default_dir (Score_element*me)
   Item * sl =  head(me,LEFT) ? Rhythmic_head::stem_l (head (me,LEFT)) :0;
   Item * sr =  head(me,RIGHT) ? Rhythmic_head::stem_l (head (me,RIGHT)) :0;  
 
-
   if (sl && sr)
     {
       if (Directional_element_interface::get (sl) == UP
diff --git a/lily/translator-ctors.cc b/lily/translator-ctors.cc
index ca1e6d516f..4418310186 100644
--- a/lily/translator-ctors.cc
+++ b/lily/translator-ctors.cc
@@ -33,7 +33,6 @@ get_translator_l (String s)
 {
   if (global_translator_dict_p->elem_b (s))
     {
-//      return (*global_translator_dict_p)[s];
 	Translator* t = (*global_translator_dict_p)[s];
 	return t;
     }
diff --git a/lily/translator-def.cc b/lily/translator-def.cc
new file mode 100644
index 0000000000..558d0786a2
--- /dev/null
+++ b/lily/translator-def.cc
@@ -0,0 +1,292 @@
+/*   
+  translator-def.cc --  implement Translator_def
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "lily-proto.hh"
+#include "translator-def.hh"
+#include "translator-group.hh"
+#include "warn.hh"
+#include "music-output-def.hh"
+
+#include "ly-smobs.icc"
+
+int
+Translator_def::print_smob (SCM smob, SCM port, scm_print_state*)
+{
+  Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
+
+  scm_puts("#<Translator_def ", port);
+  scm_display (me->type_name_, port);
+  scm_puts (">", port);
+  return 1;
+}
+
+
+SCM
+Translator_def::mark_smob (SCM smob)
+{
+  Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
+  scm_gc_mark (me->consists_name_list_);
+  scm_gc_mark (me->accepts_name_list_);
+  scm_gc_mark (me->end_consists_name_list_);
+  scm_gc_mark (me->property_ops_);  
+  scm_gc_mark (me->translator_group_type_);
+  return me->type_name_;
+}
+
+SCM push_sym;
+SCM assign_sym;
+
+static void
+foo_init ()
+{
+  push_sym = scm_permanent_object (ly_symbol2scm ("push"));
+  assign_sym = scm_permanent_object (ly_symbol2scm ("assign"));
+}
+
+ADD_SCM_INIT_FUNC(transdef, foo_init);
+
+Translator_def::Translator_def ()
+{
+  translator_group_type_ = SCM_EOL;
+  accepts_name_list_ = SCM_EOL;   
+  consists_name_list_ = SCM_EOL;
+  end_consists_name_list_ = SCM_EOL;
+  property_ops_ = SCM_EOL;
+  type_name_ = SCM_EOL;
+}
+Translator_def::~Translator_def ()
+{
+}
+
+Translator_def::Translator_def (Translator_def const & s)
+  : Input (s)
+{
+  consists_name_list_ = scm_list_copy (s.consists_name_list_);
+  end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
+  accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
+  property_ops_ = scm_list_copy (s.property_ops_);
+
+  translator_group_type_ = s.translator_group_type_;
+  type_name_ = s.type_name_;
+}
+
+
+
+void
+Translator_def::set_acceptor (SCM name, bool add)
+{
+  if (add)
+    this->accepts_name_list_ = gh_append2 (this->accepts_name_list_, gh_cons (name, SCM_EOL));
+  else
+    this->accepts_name_list_ = scm_delete_x (name, this->accepts_name_list_);
+}
+
+
+SCM
+Translator_def::modify_definition (SCM list, SCM str, bool add)
+{
+  String s = ly_scm2string (str);
+  if (!get_translator_l (s))
+    error (_ ("Program has no such type"));
+
+  if (add)
+    {
+      if (scm_memq (str, list) != SCM_BOOL_F)
+	{
+	  warning (_f("Already contains: `%s'", s));
+	  warning (_f("Not adding translator: `%s'", s));
+	}
+      else
+	list= gh_cons (str, list);
+    }
+  else
+    {
+      list = scm_delete_x (str, list);
+    }
+  return list;
+}
+
+
+
+void
+Translator_def::remove_element (SCM s)
+{
+  this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, false);
+  this->consists_name_list_ = modify_definition (this->consists_name_list_, s, false);
+}
+
+void
+Translator_def::add_element (SCM s)
+{
+  this->consists_name_list_ = modify_definition (this->consists_name_list_, s, true);
+}
+
+void
+Translator_def::add_last_element (SCM s)
+{
+  this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, true);
+}
+void
+Translator_def::add_push_property (SCM props, SCM syms,  SCM vals)
+{
+  this->property_ops_ = gh_cons (gh_list (push_sym, props, syms, vals, SCM_UNDEFINED),
+				    this->property_ops_);
+}
+
+void
+Translator_def::add_pop_property (SCM props, SCM syms)
+{
+  this->property_ops_ = gh_cons (gh_list (push_sym, props, syms, SCM_UNDEFINED),
+				  this->property_ops_);
+}
+
+/*
+  Do it. SYMS maybe a symbol or a list of symbols. VAL is
+  SCM_UNDEFINED in case of a pop
+*/
+void
+Translator_def::apply_pushpop_property (Translator_group* me,SCM syms, SCM eprop, SCM val)
+{
+  if (gh_symbol_p (syms))
+    dynamic_cast<Translator_group*>(me)->execute_single_pushpop_property (syms, eprop, val);
+  else for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
+    dynamic_cast<Translator_group*>(me)->execute_single_pushpop_property (gh_car (s), eprop, val);
+}
+
+
+
+Link_array<Translator_def>
+Translator_def::path_to_acceptable_translator (SCM type_str, Music_output_def* odef) const
+{
+  assert (gh_string_p (type_str));
+  
+  Link_array<Translator_def> accepted_arr;
+  for (SCM s = accepts_name_list_; gh_pair_p (s); s = gh_cdr (s))
+    {
+      Translator_def *t = unsmob_translator_def (odef->find_translator_l (gh_car (s)));
+      if (!t)
+	continue;
+      accepted_arr.push (t);
+    }
+
+
+  Link_array<Translator_def> best_result;
+  for (int i=0; i < accepted_arr.size (); i++)
+    if (scm_equal_p (accepted_arr[i]->type_name_, type_str) == SCM_BOOL_T)
+      {
+	best_result.push (accepted_arr[i]);
+	return best_result;
+      }
+
+  int best_depth= INT_MAX;
+  for (int i=0; i < accepted_arr.size (); i++)
+    {
+      Translator_def * g = accepted_arr[i];
+
+      Link_array<Translator_def> result
+	= g->path_to_acceptable_translator (type_str, odef);
+      if (result.size () && result.size () < best_depth)
+	{
+	  result.insert (g,0);
+	  best_result = result;
+	}
+    }
+
+  return best_result;
+}
+IMPLEMENT_UNSMOB(Translator_def,translator_def);
+IMPLEMENT_SMOBS(Translator_def);
+IMPLEMENT_DEFAULT_EQUAL_P(Translator_def);
+
+
+static SCM
+trans_list (SCM namelist, Translator_group*tg)
+{
+  SCM l = SCM_EOL;
+  for (SCM s = namelist; gh_pair_p (s) ; s = gh_cdr (s))
+    {
+      Translator * t = get_translator_l (ly_scm2string (gh_car (s)));
+      if (!t)
+	warning (_f ("can't find: `%s'", s));
+      else
+	{
+	  Translator * tr = t->clone ();
+	  SCM str = tr->self_scm ();
+	  l = gh_cons (str, l);
+
+	  tr->daddy_trans_l_ = tg;
+	  tr->output_def_l_  = tg->output_def_l_;
+
+	  scm_unprotect_object (str);
+	}
+    }
+  return l; 
+}
+
+
+Translator_group *
+Translator_def::instantiate (Music_output_def* md)
+{
+  Translator * g = get_translator_l (ly_scm2string (translator_group_type_));
+  g = g->clone (); 
+
+  Translator_group *tg = dynamic_cast<Translator_group*> (g);
+  tg->output_def_l_ = md;
+  tg->definition_ = self_scm ();
+  tg->type_str_ = ly_scm2string (type_name_);
+  SCM correct_order = scm_reverse (property_ops_); // pity of the mem.
+  for (SCM s = correct_order; gh_pair_p (s); s = gh_cdr (s))
+    {
+      SCM entry = gh_car (s);
+      SCM type = gh_car (entry);
+      entry = gh_cdr (entry); 
+      
+      if (type == push_sym)
+	{
+	  SCM val = gh_cddr (entry);
+	  val = gh_pair_p (val) ? gh_car (val) : SCM_UNDEFINED;
+
+	  apply_pushpop_property (tg, gh_car (entry), gh_cadr (entry), val);
+	}
+      else if (type == assign_sym)
+	{
+	  tg->set_property (gh_car(entry), gh_cadr (entry));
+	}
+    }
+
+  SCM l1 = trans_list (consists_name_list_, tg);
+  SCM l2 =trans_list (end_consists_name_list_,tg);
+  l1 = scm_reverse_x (l1, l2);
+  
+  tg->simple_trans_list_ = l1;
+  
+  return tg;
+}
+
+SCM
+Translator_def::clone_scm () const
+{
+  Translator_def * t = new Translator_def (*this);
+  return t->unprotected_smobify_self ();
+}
+
+SCM
+Translator_def::make_scm ()
+{
+  Translator_def* t = new Translator_def;
+  return t->unprotected_smobify_self ();
+}
+
+void
+Translator_def::add_property_assign (SCM nm, SCM val)
+{
+  this->property_ops_ = gh_cons (gh_list (assign_sym, scm_string_to_symbol (nm), val, SCM_UNDEFINED),
+				 this->property_ops_);
+}
+
diff --git a/lily/translator-group-initializer.cc b/lily/translator-group-initializer.cc
deleted file mode 100644
index b7a5aecf28..0000000000
--- a/lily/translator-group-initializer.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-	/*   
-  translator-group-initializer.cc --  implement Translator_group_initializer
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-  
- */
-
-#include "translator-group.hh"
-#include "warn.hh"
-
-
-void
-Translator_group_initializer::set_acceptor (Translator *me,SCM name, bool add)
-{
-  if (add)
-    me->accepts_name_list_ = gh_append2 (me->accepts_name_list_, gh_cons (name, SCM_EOL));
-  else
-    me->accepts_name_list_ = scm_delete_x (name, me->accepts_name_list_);
-}
-
-
-SCM
-Translator_group_initializer::modify_definition (SCM list, SCM str, bool add)
-{
-  String s = ly_scm2string (str);
-  if (!get_translator_l (s))
-    error (_ ("Program has no such type"));
-
-  if (add)
-    {
-      if (scm_memq (str, list) != SCM_BOOL_F)
-	{
-	  warning (_f("Already contains: `%s'", s));
-	  warning (_f("Not adding translator: `%s'", s));
-	}
-      else
-	list= gh_cons (str, list);
-    }
-  else
-    {
-      list = scm_delete_x (str, list);
-    }
-  return list;
-}
-
-
-
-void
-Translator_group_initializer::remove_element (Translator *me,SCM s)
-{
-  me->end_consists_name_list_ = modify_definition (me->end_consists_name_list_, s, false);
-  me->consists_name_list_ = modify_definition (me->consists_name_list_, s, false);
-}
-
-void
-Translator_group_initializer::add_element (Translator *me,SCM s)
-{
-  me->consists_name_list_ = modify_definition (me->consists_name_list_, s, true);
-}
-
-void
-Translator_group_initializer::add_last_element (Translator *me,SCM s)
-{
-  me->end_consists_name_list_ = modify_definition (me->end_consists_name_list_, s, true);
-}
-void
-Translator_group_initializer::add_push_property (Translator * me,
-						 SCM props, SCM syms,  SCM vals)
-{
-  me->property_pushes_ = gh_cons (gh_list (props, syms, vals, SCM_UNDEFINED),
-				  me->property_pushes_);
-}
-
-void
-Translator_group_initializer::add_pop_property (Translator * me,
-						 SCM props, SCM syms)
-{
-  me->property_pushes_ = gh_cons (gh_list (props, syms, SCM_UNDEFINED),
-				  me->property_pushes_);
-}
-
-/*
-  Do it. SYMS maybe a symbol or a list of symbols. VAL is
-  SCM_UNDEFINED in case of a pop
-*/
-void
-Translator_group_initializer::apply_pushpop_property (Translator *trans, SCM syms, SCM eprop, SCM val)
-{
-  if (gh_symbol_p (syms))
-    dynamic_cast<Translator_group*>(trans)->execute_single_pushpop_property (syms, eprop, val);
-  else for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
-    dynamic_cast<Translator_group*>(trans)->execute_single_pushpop_property (gh_car (s), eprop, val);
-}
diff --git a/lily/translator-group.cc b/lily/translator-group.cc
index 74cee77b61..02eb4c7fb9 100644
--- a/lily/translator-group.cc
+++ b/lily/translator-group.cc
@@ -13,6 +13,7 @@
 #include "moment.hh"
 #include "scm-hash.hh"
 #include "killing-cons.tcc"
+#include "translator-def.hh"
 
 Translator_group::Translator_group (Translator_group const&s)
   : Translator(s)
@@ -103,45 +104,8 @@ Translator_group::find_existing_translator_l (String n, String id)
   return r;
 }
 
-Link_array<Translator_group>
-Translator_group::path_to_acceptable_translator (String type, Music_output_def* odef) const
-{
-  Link_array<Translator_group> accepted_arr;
-  for (SCM s = accepts_name_list_; gh_pair_p (s); s = gh_cdr (s))
-    {
-      
-      Translator *t = odef->find_translator_l (ly_scm2string (gh_car (s)));
-      if (!t || !dynamic_cast <Translator_group *> (t))
-	continue;
-      accepted_arr.push (dynamic_cast <Translator_group *> (t));
-    }
 
 
- for (int i=0; i < accepted_arr.size (); i++)
-    if (accepted_arr[i]->type_str_ == type)
-      {
-	Link_array<Translator_group> retval;
-	retval.push (accepted_arr[i]);
-	return retval;
-      }
-
-  Link_array<Translator_group> best_result;
-  int best_depth= INT_MAX;
-  for (int i=0; i < accepted_arr.size (); i++)
-    {
-      Translator_group * g = accepted_arr[i];
-
-      Link_array<Translator_group> result
-	= g->path_to_acceptable_translator (type, odef);
-      if (result.size () && result.size () < best_depth)
-	{
-	  result.insert (g,0);
-	  best_result = result;
-	}
-    }
-
-  return best_result;
-}
 
 Translator_group*
 Translator_group::find_create_translator_l (String n, String id)
@@ -150,8 +114,8 @@ Translator_group::find_create_translator_l (String n, String id)
   if (existing)
     return existing;
 
-  Link_array<Translator_group> path
-    = path_to_acceptable_translator (n, output_def_l ());
+  Link_array<Translator_def> path
+    = unsmob_translator_def (definition_)->path_to_acceptable_translator (gh_str02scm (n.ch_C()), output_def_l ());
 
   if (path.size ())
     {
@@ -160,7 +124,7 @@ Translator_group::find_create_translator_l (String n, String id)
       // start at 1.  The first one (index 0) will be us.
       for (int i=0; i < path.size (); i++)
 	{
-	  Translator_group * new_group = dynamic_cast<Translator_group*>(path[i]->clone ());
+	  Translator_group * new_group = path[i]->instantiate (output_def_l_);
 
 	  current->add_group_translator (new_group);
 	  current = new_group;
@@ -222,10 +186,10 @@ void
 Translator_group::terminate_translator (Translator*r_l)
 {
   r_l->removal_processing();
-  Translator * trans_p =remove_translator_p (r_l);
   /*
-    forget trans_p, GC does the rest.
+    Return value ignored. GC does the rest.
    */
+  remove_translator_p (r_l);
 }
 
 
@@ -263,30 +227,30 @@ Translator_group::get_simple_translator (String type) const
 bool
 Translator_group::is_bottom_translator_b () const
 {
-  return accepts_name_list_ == SCM_EOL;
+  return unsmob_translator_def (definition_)->accepts_name_list_ == SCM_EOL;
 }
 
-
-
 Translator_group*
 Translator_group::get_default_interpreter()
 {
-  if (gh_pair_p (accepts_name_list_))
+  if (!is_bottom_translator_b ())
     {
-      String str = ly_scm2string (gh_car (accepts_name_list_));
-      Translator*t = output_def_l ()->find_translator_l (str);
+      SCM nm = unsmob_translator_def (definition_)->accepts_name_list_;
+      SCM st = output_def_l ()->find_translator_l (gh_car (nm));
+
+      Translator_def *t = unsmob_translator_def (st);
       if (!t)
 	{
-	  warning (_f ("can't find or create: `%s'", str));
-	  t = this;
+	  warning (_f ("can't find or create: `%s'", ly_scm2string (nm).ch_C()));
+	  t = unsmob_translator_def (this->definition_);
 	}
-      Translator_group * g= dynamic_cast <Translator_group*>(t->clone ());
-      add_group_translator (g);
+      Translator_group *tg = t->instantiate (output_def_l_);
+      add_group_translator (tg);
 
-      if (!g->is_bottom_translator_b ())
-	return g->get_default_interpreter ();
+      if (!tg->is_bottom_translator_b ())
+	return tg->get_default_interpreter ();
       else
-	return g;
+	return tg;
     }
   return this;
 }
@@ -313,59 +277,14 @@ Translator_group::do_print() const
 #endif
 }
 
-static SCM
-trans_list (SCM namelist, Music_output_def *mdef)
-{
-  SCM l = SCM_EOL;
-  for (SCM s = namelist; gh_pair_p (s) ; s = gh_cdr (s))
-    {
-      Translator * t = mdef->find_translator_l (ly_scm2string (gh_car (s)));
-      if (!t)
-	warning (_f ("can't find: `%s'", s));
-      else
-	{
-	  Translator * tr = t->clone ();
-	  SCM str = tr->self_scm ();
-	  l = gh_cons (str, l);
-	  scm_unprotect_object (str);
-	}
-    }
-  return l; 
-}
-
-
 void
 Translator_group::do_add_processing ()
 {
-  assert (simple_trans_list_== SCM_EOL);
-
-  SCM correct_order = scm_reverse (property_pushes_); // pity of the mem.
-  for (SCM s = correct_order; gh_pair_p (s); s = gh_cdr (s))
-    {
-      SCM entry = gh_car (s);
-      SCM val = gh_cddr (entry);
-      val = gh_pair_p (val) ? gh_car (val) : SCM_UNDEFINED;
-      
-      Translator_group_initializer::apply_pushpop_property (this, gh_car (entry),
-							    gh_cadr (entry),
-							    val);
-    }
-
-  SCM l1 = trans_list (consists_name_list_, output_def_l ());
-  SCM l2 =trans_list (end_consists_name_list_, output_def_l ());
-  l1 = scm_reverse_x (l1, l2);
-  
-  simple_trans_list_ = l1;
-  for (SCM s = l1; gh_pair_p (s) ; s = gh_cdr (s))
+  for (SCM s = simple_trans_list_; gh_pair_p (s) ; s = gh_cdr (s))
     {
       Translator * t = unsmob_translator (gh_car (s));
-
-      t->daddy_trans_l_ = this;
-      t->output_def_l_ = output_def_l_;
       t->add_processing ();
     }
-
-  
 }
 
 /*
diff --git a/lily/translator.cc b/lily/translator.cc
index 6605eaae0c..90edc46fbb 100644
--- a/lily/translator.cc
+++ b/lily/translator.cc
@@ -31,10 +31,7 @@ Translator::init ()
   simple_trans_list_ = SCM_EOL;
   trans_group_list_ = SCM_EOL;
   properties_scm_ = SCM_EOL;
-  accepts_name_list_ = SCM_EOL;   
-  consists_name_list_ = SCM_EOL;
-  end_consists_name_list_ = SCM_EOL;
-  property_pushes_ = SCM_EOL;
+  definition_ = SCM_EOL;
   daddy_trans_l_ =0;
 }
 
@@ -50,12 +47,6 @@ Translator::Translator (Translator const &s)
   : Input (s)
 {
   init ();
-  
-  consists_name_list_ = scm_list_copy (s.consists_name_list_);
-  end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
-  accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
-  property_pushes_ = scm_list_copy (s.property_pushes_);
-  
   output_def_l_ = s.output_def_l_;
   type_str_ = s.type_str_;
 
@@ -233,12 +224,11 @@ SCM
 Translator::mark_smob (SCM sm)
 {
   Translator * me = (Translator*) SCM_CELL_WORD_1(sm);
-  scm_gc_mark (me->consists_name_list_);
-  scm_gc_mark (me->accepts_name_list_);
-  scm_gc_mark (me->end_consists_name_list_);
   scm_gc_mark (me->simple_trans_list_);
   scm_gc_mark (me->trans_group_list_);
-  scm_gc_mark (me->property_pushes_);
+  scm_gc_mark (me->definition_);  
+  scm_gc_mark (me->properties_scm_);  
+
   return me->properties_scm_;
 }
 
diff --git a/lilypond-mode.el b/lilypond-mode.el
index b035151c54..237f0a347d 100644
--- a/lilypond-mode.el
+++ b/lilypond-mode.el
@@ -44,7 +44,7 @@
 		     "duration" "font" "grace" "header" "in" "lyrics"
 		     "key" "keysignature" "mark" "musicalpitch"
 		     "time" "times" "midi" "mm" "name" "notenames"
-		     "notes" "partial" "paper" "penalty" "property" "pt"
+		     "notes" "partial" "paper" "penalty" "push" "pop" "property" "pt"
 		     "relative" "remove" "repeat" "repetitions" "addlyrics"
 		     "scm" "scmfile" "score" "script"
 		     "shape" "skip" "textscript" "tempo" "translator" "transpose"
diff --git a/ly/engraver.ly b/ly/engraver.ly
index 8b6a2f63eb..c34e936bcb 100644
--- a/ly/engraver.ly
+++ b/ly/engraver.ly
@@ -76,8 +76,8 @@ RhythmicStaffContext=\translator{
 	\consists "Separating_line_group_engraver";	
 	\name RhythmicStaff;
 
-	\pushproperty #'basicVoltaSpannerProperties #'minimum-space #15  % urg, in \pt
-	\pushproperty #'basicVoltaSpannerProperties #'padding #5  % urg, in \pt
+	basicVoltaSpannerProperties \push #'minimum-space =  #15  % urg, in \pt
+	basicVoltaSpannerProperties \push #'padding =  #5  % urg, in \pt
 
 
 
@@ -160,12 +160,18 @@ GraceContext=\translator {
 
 	\consists "Property_engraver";
 
-	\pushproperty #'basicStemProperties #'style #"grace"
-	\pushproperty #'basicStemProperties #'flag-style #"grace"
-	\pushproperty #'basicStemProperties #'stem-length #6.0
-	\pushproperty #'basicStemProperties #'direction #1
-	\pushproperty #'(basicNoteHeadProperties basicStemProperties basicBeamProperties basicTextScriptProperties basicSlurProperties basicLocalKeyProperties) #'font-size #-1
-		
+	basicStemProperties \push  #'style = #"grace"
+	basicStemProperties \push  #'flag-style = #"grace"
+	basicStemProperties \push  #'stem-length = #6.0
+	basicStemProperties \push  #'direction = #1
+
+	basicNoteHeadProperties \push #'font-size = #-1
+	basicStemProperties \push #'font-size = #-1
+	basicBeamProperties \push #'font-size = #-1
+	basicTextScriptProperties \push #'font-size = #-1
+	basicSlurProperties \push #'font-size = #-1
+	basicLocalKeyProperties \push #'font-size = #-1
+
 	weAreGraceContext = ##t 
 	graceAccidentalSpace= 1.5 * \staffspace;
 };
@@ -705,7 +711,7 @@ ScoreContext = \translator {
 		(visibility-lambda . ,begin-of-line-visible)
 		(name . "stanza number")
 	)
-	staffSymbolBasicProperties = #`(
+	basicStaffSymbolProperties = #`(
 		(interfaces . (staff-symbol-interface ))
 		(molecule-callback . ,Staff_symbol::brew_molecule)
 		(staff-space . 1.0)
diff --git a/ly/performer.ly b/ly/performer.ly
index 4529859e7c..0ad41e658f 100644
--- a/ly/performer.ly
+++ b/ly/performer.ly
@@ -6,11 +6,6 @@ StaffContext = \translator {
 	\name Staff;
 	\accepts Voice;
 
-	\accepts VoiceOne;		% ugh.
-	\accepts VoiceTwo;
-	\accepts VoiceThree;
-	\accepts VoiceFour;
-
 	\consists "Key_performer";
 	\consists "Time_signature_performer";
 	\consists "Tempo_performer";
diff --git a/make/lilypond.spec.in b/make/lilypond.spec.in
index bea597ab76..d41de51303 100644
--- a/make/lilypond.spec.in
+++ b/make/lilypond.spec.in
@@ -91,7 +91,9 @@ fi
 %doc mudela-mode.el
 
 %ifnos cygwin
-%{_prefix}/bin/abc2ly
+%{_prefix}/bin/etf2ly
+%{_prefix}/bin/musedata2ly
+%{_prefix}/bin/pmx2ly
 %{_prefix}/bin/convert-mudela
 %{_prefix}/bin/mudela-book
 %{_prefix}/bin/ly2dvi
diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm
index 69e8b37573..3611773a1a 100644
--- a/make/out/lilypond.lsm
+++ b/make/out/lilypond.lsm
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.3.84
-Entered-date: 02SEP00
+Version: 1.3.85
+Entered-date: 08SEP00
 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.84.tar.gz 
+	1000k lilypond-1.3.85.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-	1000k lilypond-1.3.84.tar.gz 
+	1000k lilypond-1.3.85.tar.gz 
 Copying-policy: GPL
 End
diff --git a/make/out/lilypond.spec b/make/out/lilypond.spec
index bc861526da..5dfe670fe5 100644
--- a/make/out/lilypond.spec
+++ b/make/out/lilypond.spec
@@ -1,9 +1,9 @@
 Name: lilypond
-Version: 1.3.84
+Version: 1.3.85
 Release: 1
 Copyright: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.84.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.85.tar.gz
 Summary: A program for printing sheet music.
 URL: http://www.cs.uu.nl/~hanwen/lilypond
 # Icon: lilypond-icon.gif
@@ -91,7 +91,9 @@ fi
 %doc mudela-mode.el
 
 %ifnos cygwin
-%{_prefix}/bin/abc2ly
+%{_prefix}/bin/etf2ly
+%{_prefix}/bin/musedata2ly
+%{_prefix}/bin/pmx2ly
 %{_prefix}/bin/convert-mudela
 %{_prefix}/bin/mudela-book
 %{_prefix}/bin/ly2dvi
diff --git a/scripts/mudela-book.py b/scripts/mudela-book.py
index 610c29e709..c60924d434 100644
--- a/scripts/mudela-book.py
+++ b/scripts/mudela-book.py
@@ -1,43 +1,7 @@
 #!@PYTHON@
 # vim: set noexpandtab:
-import time
-t1 = time.clock()
-
-# support bruk av convert-mudela
-#
-# option:
-# 11pt, 13pt, 16pt, 20pt, 26pt
-# singleline
-# multiline
-# fragment  (used when a comment containg \score confuses mudela-book)
-# nonfragment (probably not needed)
-# verbatim
-
-# latex only options:
-# eps
-# 
-
-# command line options
-# --defalt-mudela-fontsize
-# --force-mudela-fontsize
-# --outname
-# --force-verbatim make all mudela verbatim. Maybe not that useful
-# --dependencies
-# --dep-prefix
-# --no-pictures
-# --no-lily
 # TODO: Figure out clean set of options.
-
-# BUG: does not handle \verb|\begin{verbatim}\end{verbatim}| correctly.
-# Should make a joint RE for \verb and \begin, \end{verbatim}
-
-# TODO: add an option to read the .ly files from a previous run and dump
-# the .tex file, so you can do
-#
-# * mudela-book file.tex
-# * convert-mudela *.ly
-# * mudela-book --read-lys *.ly
-#
+# add support for .lilyrc
 
 import os
 import stat
@@ -48,8 +12,6 @@ import sys
 import __main__
 
 
-initfile = ''
-
 
 program_version = '@TOPLEVEL_VERSION@'
 if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
@@ -65,7 +27,6 @@ g_do_pictures = 1
 g_num_cols = 1
 format = ''
 g_run_lilypond = 1
-g_use_hash = 1
 no_match = 'a\ba'
 
 default_music_fontsize = 16
@@ -104,22 +65,20 @@ def get_linewidth(cols, paper, fontsize):
 
 option_definitions = [
   ('EXT', 'f', 'format', 'set format.  EXT is one of texi and latex.'),
-  ('DIM',  '', 'default-music-fontsize', 'default fontsize for music.  DIM is assumed to in points'),
+  ('DIM',  '', 'default-music-fontsize', 'default fontsize for music.  DIM is assumed to be in points'),
   ('DIM',  '', 'default-mudela-fontsize', 'deprecated, use --default-music-fontsize'),
-  ('', 'h', 'help', 'print help'),
-  ('DIR', 'I', 'include', 'include path'),
-  ('', '', 'init', 'mudela-book initfile'),
-  ('DIM', '', 'force-music-fontsize', 'force fontsize for all inline mudela. DIM is assumed to in points'),
+  ('DIM', '', 'force-music-fontsize', 'force fontsize for all inline mudela. DIM is assumed be to in points'),
   ('DIM', '', 'force-mudela-fontsize', 'deprecated, use --force-music-fontsize'),
-  ('', '', 'force-verbatim', 'make all mudela verbatim'),
+  ('DIR', 'I', 'include', 'include path'),
   ('', 'M', 'dependencies', 'write dependencies'),
+  ('PREF', '',  'dep-prefix', 'prepend PREF before each -M dependency'),
   ('', 'n', 'no-lily', 'don\'t run lilypond'),
   ('', '', 'no-pictures', "don\'t generate pictures"),
   ('', '', 'read-lys', "don't write ly files."),
-  ('FILE', 'o', 'outname', 'prefix for filenames'),
-  ('', 'v', 'version', 'print version information' ),
-  ('PREF', '',  'dep-prefix', 'prepend PREF before each -M dependency'),
+  ('FILE', 'o', 'outname', 'filename main output file'),
   ('FILE', '', 'outdir', "where to place generated files"),
+  ('', 'v', 'version', 'print version information' ),
+  ('', 'h', 'help', 'print help'),
   ]
 
 # format specific strings, ie. regex-es for input, and % strings for output
@@ -194,16 +153,16 @@ re_dict = {
 		  'option-sep' : ', *',
 		  'header': r"""\\documentclass(\[.*?\])?""",
 		  'preamble-end': '\\\\begin{document}',
-		  'verbatim': r"""(?s)\\begin{verbatim}(?P<code>.*?)\\end{verbatim}""",
-		  'verb': r"""\\verb(.)(?P<code>.*?)\1""",
+		  'verbatim': r"""(?s)(?P<code>\\begin{verbatim}.*?\\end{verbatim})""",
+		  'verb': r"""(?P<code>\\verb(?P<del>.).*?(?P=del))""",
 		  'mudela-file': r'\\mudelafile(\[(?P<options>.*?)\])?\{(?P<filename>.+)}',
-		  'mudela' : '\\\\mudela(\[(?P<options>.*?)\])?{(?P<code>.*?)}',
+		  'mudela' : '(?m)\\\\mudela(\[(?P<options>.*?)\])?{(?P<code>.*?)}',
+		  #'mudela-block': r"""(?m)^[^%]*?\\begin(\[(?P<options>.*?)\])?{mudela}(?P<code>.*?)\\end{mudela}""",
 		  'mudela-block': r"""(?s)\\begin(\[(?P<options>.*?)\])?{mudela}(?P<code>.*?)\\end{mudela}""",
-		  'interesting-cs': '\\\\(chapter|section|twocolumn|onecolumn)',
 		  'def-post-re': r"""\\def\\postMudelaExample""",
 		  'def-pre-re': r"""\\def\\preMudelaExample""",		  
 		  'intertext': r',?\s*intertext=\".*?\"',
-		  'ignore': no_match,
+		  'ignore': r"(?m)(?P<code>%.*?^)",
 		  'numcols': r"(?P<code>\\(?P<num>one|two)column)",
 		  },
 	
@@ -213,14 +172,13 @@ re_dict = {
 		 'header': no_match,
 		 'preamble-end': no_match,
 		 'verbatim': r"""(?s)(?P<code>@example\s.*?@end example\s)""",
-		 'verb': r"""@code{(?P<code>.*?)}""",
+		 'verb': r"""(?P<code>@code{.*?})""",
 		 'mudela-file': '@mudelafile(\[(?P<options>.*?)\])?{(?P<filename>[^}]+)}',
 		 'mudela' : '@mudela(\[(?P<options>.*?)\])?{(?P<code>.*?)}',
 		 'mudela-block': r"""(?s)@mudela(\[(?P<options>.*?)\])?\s(?P<code>.*?)@end mudela\s""",
-		 'interesting-cs': r"""[\\@](chapter|section)""",
 		  'option-sep' : ', *',
 		  'intertext': r',?\s*intertext=\".*?\"',
-		  'ignore': r"(?s)@ignore\s(.*?)@end ignore\s",
+		  'ignore': r"(?s)(?P<code>@ignore\s.*?@end ignore)\s",
 		  'numcols': no_match,
 		 }
 	}
@@ -396,7 +354,7 @@ def find_file (name):
 		return ''
 
 def do_ignore(match_object):
-	return []
+	return [('ignore', match_object.group('code'))]
 
 def make_verbatim(match_object):
 	return [('verbatim', match_object.group('code'))]
@@ -468,7 +426,9 @@ def chop_chunks(chunks, re_name, func):
                     str = ''
                 else:
                     newchunks.append (('input', str[:m.start (0)]))
-                    newchunks.extend(func(m))
+                    #newchunks.extend(func(m))
+		    # python 1.5 compatible:
+		    newchunks = newchunks + func(m)
                     str = str [m.end(0):]
         else:
             newchunks.append(c)
@@ -493,7 +453,6 @@ def read_doc_file (filename):
 	# we have to check for verbatim before doing include,
 	# because we don't want to include files that are mentioned
 	# inside a verbatim environment
-	chunks = chop_chunks(chunks, 'ignore', do_ignore)
 	chunks = chop_chunks(chunks, 'verbatim', make_verbatim)
 	chunks = chop_chunks(chunks, 'verb', make_verb)
 	#ugh fix input
@@ -502,25 +461,8 @@ def read_doc_file (filename):
 	return chunks
 
 
-def advance_counters (counter, str):
-	"""Advance chap/sect counters,
-	Return the new counter tuple
-	"""
-	(chapter, section, count) = counter
-	while str:
-		m = get_re ('interesting-cs').search(str)
-		if not m:
-			break
-		str = str[m.end(0):]
-		g = m.group (1)
-		if g == 'chapter':#ugh use dict
-			(chapter, section, count)  = (chapter + 1, 0, 0)
-		elif g == 'section':
-			(section, count)  = (section + 1, 0)
-	return (chapter, section, count)
-
-taken_file_names = []
-def schedule_mudela_block (basename, chunk, extra_opts):
+taken_file_names = {}
+def schedule_mudela_block (chunk, extra_opts):
 	"""Take the body and options from CHUNK, figure out how the
 	real .ly should look, and what should be left MAIN_STR (meant
 	for the main file).  The .ly is written, and scheduled in
@@ -539,15 +481,16 @@ def schedule_mudela_block (basename, chunk, extra_opts):
 	assert type == 'mudela'
 	opts = opts +  extra_opts
 	file_body = compose_full_body (body, opts)
-	if __main__.g_use_hash:
-		basename = `abs(hash (file_body))`
+	basename = `abs(hash (file_body))`
 	for o in opts:
 		m = re.search ('filename="(.*?)"', o)
 		if m:
-			basename = m.group (1)#ugh add check if more than
-			#one file has the same name
-			assert basename not in taken_file_names
-			taken_file_names.append(basename)
+			basename = m.group (1)
+			if not taken_file_names.has_key(basename):
+			    taken_file_names[basename] = 0
+			else:
+			    taken_file_names[basename] = taken_file_names[basename] + 1
+			    basename = basename + "-%i" % taken_file_names[basename]
 	# writes the file if necessary, returns true if it was written
 	if not g_read_lys:
 		update_file(file_body, os.path.join(g_outdir, basename) + '.ly')
@@ -587,16 +530,11 @@ def schedule_mudela_block (basename, chunk, extra_opts):
 	return ('mudela', newbody, opts, todo, basename)
 
 def process_mudela_blocks(outname, chunks, global_options):#ugh rename
-	(chap,sect,count) = (0,0,0)
 	newchunks = []
 	# Count sections/chapters.
 	for c in chunks:
-		if c[0] == 'input':
-			(chap,sect,count) = advance_counters((chap,sect,count), c[1])
-		elif c[0] == 'mudela':
-			base = '%s-%d.%d.%d' % (outname, chap, sect, count)
-			count = count + 1
-			c = schedule_mudela_block (base, c, global_options)
+		if c[0] == 'mudela':
+			c = schedule_mudela_block (c, global_options)
 		elif c[0] == 'numcols':
 			__main__.g_num_cols = c[2]
 		newchunks.append (c)
@@ -781,8 +719,9 @@ def do_file(input_filename):
 	chunks = chop_chunks(chunks, 'mudela', make_mudela)
 	chunks = chop_chunks(chunks, 'mudela-file', make_mudela_file)
 	chunks = chop_chunks(chunks, 'mudela-block', make_mudela_block)
-	chunks = chop_chunks(chunks, 'numcols', do_columns)
 	#for c in chunks: print c, "\n"
+	chunks = chop_chunks(chunks, 'ignore', do_ignore)
+	chunks = chop_chunks(chunks, 'numcols', do_columns)
 	global_options = scan_preamble(chunks[0][1])
 	chunks = process_mudela_blocks(my_outname, chunks, global_options)
 	# Do It.
@@ -805,8 +744,7 @@ def do_file(input_filename):
 	sys.stderr.write ("Writing `%s'\n" % foutn)
 	fout = open (foutn, 'w')
 	for c in chunks:
-		#if c[1] is not None:
-			fout.write (c[1])
+		fout.write (c[1])
 	fout.close ()
 
 	if do_deps:
@@ -828,11 +766,10 @@ for opt in options:
 
 	if o == '--include' or o == '-I':
 		include_path.append (a)
-	elif o == '--version':
+	elif o == '--version' or o == '-v':
 		print_version ()
 		sys.exit  (0)
-
-	elif o == '--format' or o == '-o':
+	elif o == '--format' or o == '-f':
 		__main__.format = a
 	elif o == '--outname' or o == '-o':
 		if len(files) > 1:
@@ -844,7 +781,7 @@ for opt in options:
 		help ()
 	elif o == '--no-lily' or o == '-n':
 		__main__.g_run_lilypond = 0
-	elif o == '--dependencies':
+	elif o == '--dependencies' or o == '-M':
 		do_deps = 1
 	elif o == '--default-music-fontsize':
 		default_music_fontsize = string.atoi (a)
@@ -856,9 +793,6 @@ for opt in options:
 	elif o == '--force-mudela-fontsize':
 		print "--force-mudela-fontsize is deprecated, use --default-mudela-fontsize"
 		g_force_mudela_fontsize = string.atoi(a)
-
-	elif o == '--init':
-		initfile =  a
 	elif o == '--dep-prefix':
 		g_dep_prefix = a
 	elif o == '--no-pictures':
@@ -877,10 +811,6 @@ if g_outdir:
 for input_filename in files:
 	do_file(input_filename)
 	
-
-
-t2 = time.clock()
-print "Time:", t2-t1
 #
 # Petr, ik zou willen dat ik iets zinvoller deed,
 # maar wat ik kan ik doen, het verandert toch niets?
diff --git a/scripts/pmx2ly.py b/scripts/pmx2ly.py
index 0f656fe0bf..afe4c35335 100644
--- a/scripts/pmx2ly.py
+++ b/scripts/pmx2ly.py
@@ -1,6 +1,15 @@
 #!@PYTHON@
 
-# (urg! wat een pokkeformaat (pokkenformaat?))  
+#
+#
+#
+# 
+#
+#
+
+
+#fixme: block openings aren't parsed.
+
 import os
 import string
 import sys
@@ -16,14 +25,6 @@ if version == '@' + 'TOPLEVEL_VERSION' + '@':
 def encodeint (i):
 	return chr ( i  + ord ('A'))
 
-def stripcomment (l):
-	return re.sub ('[ \t]*%.*$\n', '', l)
-	
-def stripwhite (l):
-	return re.sub ('[ \n\t]+', ' ', l)
-	
-def stripeols (l):
-	return re.sub ('^ ',  '', re.sub (' $', '', l))
 	
 actab = {-2: 'eses', -1: 'es', 0 : '', 1: 'is', 2:'isis'}
 
@@ -115,6 +116,13 @@ class Barcheck :
 	def dump (self):
 		return '|\n'
 
+
+class Meter :
+	def __init__ (self,nums):
+		self.nums = nums
+	def dump (self):
+		return ' %{ FIXME: meter change %} '
+		
 class Beam:
 	def __init__ (self, ch):
 		self.char = ch
@@ -231,7 +239,6 @@ class Staff:
 			v.number = i
 			i = i+1
 	def set_clef (self, letter):
-
 		clstr = clef_table[letter]
 		self.voices[0].add_nonchord (Clef (clstr))
 		
@@ -527,26 +534,30 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20]))
 					
 		return str
 	
-	def clean (self, ls):
-		ls = map (stripcomment, ls)
-		ls = map (stripwhite, ls)
-		ls = map (stripeols, ls)
-
-
-		ls = filter (lambda x: x <> '', ls)
-		return ls
 
 	def parse_header  (self, ls):
+		while ls[0][0] == '%':
+			ls = ls[1:]
 
 		opening = ls[0]
 		ls = ls[1:]
-
-
-		opening = map (string.atoi, re.split ('[\t ]+', opening))
+		
+		opening = re.sub ('^[ \t]+', '', opening)
+		opening = re.sub ('[ \t]+$', '', opening) 		
+		opening = re.split ('[\t ]+', opening)
 
 		(no_staffs, no_instruments, timesig_num,timesig_den, ptimesig_num,
-		 ptimesig_den, pickup_beats,keysig_number) = tuple (opening)
+		 ptimesig_den, pickup_beats,keysig_number) = opening
+		(no_staffs, no_instruments, timesig_num, timesig_den, ptimesig_num, ptimesig_den, keysig_number) = tuple (map (string.atoi , [no_staffs, no_instruments, timesig_num, timesig_den, ptimesig_num, ptimesig_den, keysig_number]))
+		try: 
+			pickup_beats = string.atoi (pickup_beats)
+		except ValueError:
+			pickup_beats = string.atof (pickup_beats)
+		
 
+		while ls[0][0] == '%':
+			ls = ls[1:]
+			
 		opening = ls[0]
 		ls = ls[1:]
 
@@ -560,21 +571,25 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20]))
 			ls = ls[1:]
 
 
+		while ls[0][0] == '%':
+			ls = ls[1:]
+
 		l = ls[0]
 		ls = ls[1:]
 
-
 		self.set_staffs (no_staffs)
+
 		for s in self.staffs:
 			s.set_clef(l[0])
 			l = l[1:]
 
 		# dump path 
+		while ls[0][0] == '%':
+			ls = ls[1:]
+
 		ls = ls[1:] 
 
 		# dump more ?
-		ls = ls[2:]
-
 		return ls
 
 	def parse_ornament (self, left):
@@ -629,11 +644,42 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20]))
 		return left
 	
 	def parse_body (self, left):
-		left = re.sub ('[ \t\n]+',   ' ', left)
-
+		preamble = 1
+		
 		while left:
 			c = left[0]
-			if c in 'Gzabcdefgr':
+			if c == '%':
+				f = string.find (left, '\n')
+				if f < 0:
+					left = ''
+				left = left[f+1:]
+			elif c == 'm':
+				left = left[1:]
+				m = re.match ('([o0-9]/[o0-9]/[o0-9]/[o0-9])', left)
+				if m:
+					nums = m.group (1)
+					left = left[len (nums):]
+					nums = map (string.atoi , nums)
+					self.current_voice ().add_nonchord (Meter (nums))
+					continue
+
+				m= re.match ('([0-9o]+)', left)
+				if m:
+					nums = m.group (1)
+					self.current_voice ().add_nonchord (Meter (map (string.atoi (nums))))
+					continue
+				
+			elif left[0] in 'lh':
+				f = string.find (left, '\n')
+				if f <0 :
+					left = ''
+				else:
+					left = left[f+1:]
+					
+				f = string.find (left, '\n')
+				title = left[:f]
+				left=left[f+1:]
+			elif c in 'Gzabcdefgr':
 				left = self.parse_note (left)
 			elif c in DIGITS + 'n#-':
 				left = self.parse_basso_continuo (left)
@@ -662,9 +708,6 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20]))
 Huh? Unknown directive `%s', before `%s'""" % (c, left[:20] ))
 				left = left[1:]
 
-		for c in self.staffs:
-			c.calculate ()
-
 	def dump (self):
 		str = ''
 
@@ -679,10 +722,14 @@ Huh? Unknown directive `%s', before `%s'""" % (c, left[:20] ))
 
 	def parse (self,fn):
 		ls = open (fn).readlines ()
-		ls = self.clean (ls)
 		ls = self.parse_header (ls)
 		left = string.join (ls, ' ')
+
+		print left
 		self.parse_body (left)
+		for c in self.staffs:
+			c.calculate ()
+
 		
 
 
diff --git a/stepmake/stepmake/help2man-rules.make b/stepmake/stepmake/help2man-rules.make
index 493d7acff5..8f90dc312a 100644
--- a/stepmake/stepmake/help2man-rules.make
+++ b/stepmake/stepmake/help2man-rules.make
@@ -12,7 +12,8 @@ $(outdir)/%.1: out/%.1
 endif
 
 $(outdir)/%.1: $(outdir)/%
-	$(PERL) $(depth)/$(builddir)/buildscripts/$(outbase)/help2man $< > $@ || \
+	echo "generating man page from --help"
+	@$(PERL) $(depth)/$(builddir)/buildscripts/$(outbase)/help2man $< > $@ || \
 	(echo ""; echo "Apparently the man pages failed to build. This is";\
 	echo "no problem, since they don't contain any information anyway.";\
 	echo "Please run make again, and be prepared for NO manual pages.")
-- 
2.39.5