From 64d55ba1ace6eb1a4e8e1798a0e377bff19ae5cc Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Mon, 16 Dec 1996 11:45:20 +0100
Subject: [PATCH] release: 0.0.14

---
 .dstreamrc             |  12 ++--
 Documentation/Makefile |   2 +-
 Documentation/design   |  25 +++++++++
 Sources.make           |  23 ++++----
 Variables.make         |   2 +-
 flower/Makefile        |  23 ++------
 flower/Variables.make  |  19 +++++++
 flower/assoc.hh        |   3 +-
 flower/cursor.hh       |   2 +-
 flower/cursor.inl      |   2 +-
 flower/fproto.hh       |   3 -
 flower/make_version    |  11 ++++
 flower/plist.hh        |   2 +-
 hdr/clef.hh            |   4 +-
 hdr/command.hh         |   4 +-
 hdr/getcommand.hh      |  22 +++++---
 hdr/identifier.hh      |  41 ++++++--------
 hdr/identparent.hh     |  30 ++++++++++
 hdr/inputcommand.hh    |  38 +++++++++++++
 hdr/inputcommands.hh   |  15 ++---
 hdr/inputmusic.hh      |  46 +++++++++------
 hdr/inputscore.hh      |  29 ++++++++++
 hdr/inputstaff.hh      |  33 +++++++++++
 hdr/key.hh             |   6 +-
 hdr/lookup.hh          |   4 +-
 hdr/main.hh            |   2 +-
 hdr/melodicstaff.hh    |   2 +-
 hdr/meter.hh           |   4 +-
 hdr/pcol.hh            |   3 +-
 hdr/proto.hh           |   4 +-
 hdr/rhythmstaff.hh     |   1 -
 hdr/sccol.hh           |   2 +
 hdr/score.hh           |   9 +--
 hdr/staff.hh           |  13 ++---
 hdr/stcol.hh           |   1 +
 hdr/tex.hh             |   5 ++
 kortjakje.ly           |  20 ++++---
 maartje.ly             |  29 +++++-----
 pavane.ly              |  24 ++++----
 src/beam.cc            |   1 +
 src/calcideal.cc       |  62 +++++++++++++--------
 src/clef.cc            |   2 +-
 src/getcommands.cc     |  65 ++-------------------
 src/idealspacing.cc    |  30 ++++++++++
 src/identifier.cc      |  28 ----------
 src/inputcommand.cc    | 124 +++++++++++++++++++++++++++++++++++++++++
 src/inputcommands.cc   |  54 +++++++++---------
 src/inputcursor.cc     |  19 ++++---
 src/inputmusic.cc      |  72 ++++++++++++++++++++++--
 src/inputscore.cc      |  61 ++++++++++++++++++++
 src/inputstaff.cc      |  79 ++++++++++++++++++++++++++
 src/key.cc             |   6 +-
 src/lexer.l            |  27 +++++----
 src/linespace.cc       |   1 +
 src/localkeyitem.cc    |   1 +
 src/lookup.cc          |   3 +-
 src/melodicstaff.cc    |  11 +---
 src/meter.cc           |   5 +-
 src/parser.y           | 111 +++++++++++++++++-------------------
 src/pcol.cc            |  49 +++++-----------
 src/pscore.cc          |  15 ++---
 src/rhythmstaff.cc     |   7 ---
 src/sccol.cc           |  21 +++++++
 src/score.cc           |  87 +++++++++++------------------
 src/scores.cc          |  17 +++---
 src/simpleprint.cc     |   2 +-
 src/simplewalker.cc    |   4 +-
 src/slur.cc            |   1 +
 src/staff.cc           |  58 ++++---------------
 src/stcol.cc           |   3 +-
 src/stem.cc            |   5 +-
 src/table.cc           |  12 ++--
 src/template3.cc       |   4 ++
 src/tex.cc             |   9 +++
 src/texbeam.cc         |   9 ++-
 src/texslur.cc         |  27 +++++++--
 76 files changed, 1029 insertions(+), 583 deletions(-)
 create mode 100644 Documentation/design
 create mode 100644 flower/Variables.make
 create mode 100755 flower/make_version
 create mode 100644 hdr/identparent.hh
 create mode 100644 hdr/inputcommand.hh
 create mode 100644 hdr/inputscore.hh
 create mode 100644 hdr/inputstaff.hh
 create mode 100644 src/idealspacing.cc
 delete mode 100644 src/identifier.cc
 create mode 100644 src/inputcommand.cc
 create mode 100644 src/inputscore.cc
 create mode 100644 src/inputstaff.cc

diff --git a/.dstreamrc b/.dstreamrc
index 2eb8e1df67..64944330bc 100644
--- a/.dstreamrc
+++ b/.dstreamrc
@@ -1,27 +1,27 @@
 #class name		silence?
 
 yyFlexLexer		1
-PCol			1
-Score			1
+PCol			0
 Score_column		1
 Ineq_constrained_qp 	1
 Spacing_problem 	1
 Colinfo			1
 Mixed_qp		1
 PScore			1
-Parser			1
+Parser			0
 Lexer			1
 parse_duration		1
 parse_pitch		1
 Col_configuration	1
-Command			1
-Score_commands		1
 Note_req		1
 Rhythmic_req		1
 Rest_req		1
 delete_identifiers	1
+Command			0
+Staff_commands		0
 Staff			0
+Score			0
 Voice			0
 Voice_element		0
-Request			1
+Request			0
 Input_cursor		1
\ No newline at end of file
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 383026e355..ea2f12ed55 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,6 +1,6 @@
 
 DOCFILES=commands CodingStyle algorithms Makefile breaking\
-	slurfont pointers
+	slurfont pointers design
 
 dist:
 	ln $(DOCFILES) $(DDIR)/Documentation/
\ No newline at end of file
diff --git a/Documentation/design b/Documentation/design
new file mode 100644
index 0000000000..58cd69a0c5
--- /dev/null
+++ b/Documentation/design
@@ -0,0 +1,25 @@
+LilyPond is a "5-pass" system:
+
+1. Parsing:
+
+No difficult algorithms. Associated datastructures have prefix Input
+(eg Input_score, Input_command)
+
+2. Processing:
+
+Requests are processed and granted. In this step data-structures for
+3. are created and filled with data: PScore, PCol, PStaff
+
+3. Calculation:
+
+This step uses structures which have names starting with 'P'.
+linebreaks and horizontal positions of PCols are determined. Line_of_*
+generated.
+
+4. Postprocesing:
+
+Some items and all spanners need computation after the PCol positions
+are determined.
+
+5. Output
+
diff --git a/Sources.make b/Sources.make
index 1dcc72a3c7..7aa12eb13b 100644
--- a/Sources.make
+++ b/Sources.make
@@ -6,7 +6,7 @@ hdr=    qlp.hh linespace.hh qlpsolve.hh\
 	const.hh glob.hh molecule.hh  boxes.hh pscore.hh item.hh tex.hh\
 	request.hh voice.hh command.hh staff.hh  linestaff.hh \
 	tstream.hh rhythmstaff.hh\
-	parseconstruct.hh  debug.hh globvars.hh keyword.hh\
+	parseconstruct.hh debug.hh globvars.hh keyword.hh\
 	misc.hh score.hh notename.hh lexer.hh symtable.hh\
 	symbol.hh main.hh dimen.hh paper.hh lookup.hh\
 	sccol.hh stcol.hh staffcommands.hh melodicstaff.hh\
@@ -15,9 +15,13 @@ hdr=    qlp.hh linespace.hh qlpsolve.hh\
 	swalker.hh bar.hh meter.hh accidental.hh\
 	key.hh keyitem.hh localkeyitem.hh simplewalker.hh\
 	clef.hh clefitem.hh slur.hh inputcommands.hh\
-	getcommand.hh inputmusic.hh
+	getcommand.hh inputmusic.hh \
+	inputscore.hh inputstaff.hh identparent.hh\
+	inputcommand.hh
 
-mycc=   qlp.cc qlpsolve.cc \
+mycc=   qlp.cc qlpsolve.cc leastsquares.cc\
+	inputcommands.cc inputmusic.cc	inputcursor.cc\
+	inputscore.cc inputstaff.cc\
 	break.cc linespace.cc molecule.cc staffline.cc\
 	pscore.cc tex.cc item.cc pcol.cc staff.cc \
 	rhythmstaff.cc 	score.cc note.cc  main.cc misc.cc\
@@ -25,17 +29,16 @@ mycc=   qlp.cc qlpsolve.cc \
 	keyword.cc linestaff.cc table.cc command.cc\
 	warn.cc debug.cc symtable.cc boxes.cc\
 	pstaff.cc  tstream.cc\
-	calcideal.cc scores.cc identifier.cc \
+	calcideal.cc scores.cc  \
 	dimen.cc paper.cc lookup.cc staffcommands.cc\
 	sccol.cc stcol.cc getcommands.cc simplestaff.cc\
 	melodicstaff.cc simpleprint.cc stem.cc\
-	spanner.cc notehead.cc leastsquares.cc beam.cc\
-	texbeam.cc rest.cc swalker.cc scoreline.cc\
+	spanner.cc notehead.cc  \
+	rest.cc swalker.cc scoreline.cc\
 	simplewalker.cc bar.cc meter.cc accidental.cc\
-	key.cc keyitem.cc localkeyitem.cc\
-	clef.cc clefitem.cc texslur.cc slur.cc\
-	inputcommands.cc inputmusic.cc\
-	inputcursor.cc\
+	keyitem.cc localkeyitem.cc\
+	clefitem.cc texbeam.cc  texslur.cc clef.cc key.cc slur.cc beam.cc\
+	 idealspacing.cc inputcommand.cc\
 	template1.cc template2.cc template3.cc template4.cc\
 	version.cc
 
diff --git a/Variables.make b/Variables.make
index 87c92fc64d..886a59aa4b 100644
--- a/Variables.make
+++ b/Variables.make
@@ -18,7 +18,7 @@ EXTRACXXFLAGS=-pipe -Wall -W  -pedantic
 # version info
 MAJVER=0
 MINVER=0
-PATCHLEVEL=13
+PATCHLEVEL=14
 VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
 
 # directories
diff --git a/flower/Makefile b/flower/Makefile
index 56e0da5e16..89e3bd6f5c 100644
--- a/flower/Makefile
+++ b/flower/Makefile
@@ -1,20 +1,6 @@
-MAJVER=1
-MINVER=0
-PATCHLEVEL=13
+include Variables.make
 
-PACKAGENAME=flower
-VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
-DNAME=$(PACKAGENAME)-$(VERSION)
-DEFINES=-DNDEBUG -O2
-#DEFINES=-g
-CXXFLAGS+=$(DEFINES)  -Wall -W -pedantic
-
-include Sources.make
-
-obs=$(cc:.cc=.o)
-staticlib=libflower.a
-
-$(staticlib): $(obs)
+$(staticlib): $(obs) fversion.hh
 	$(AR) cr libflower.a $(obs)
 
 include depend
@@ -29,8 +15,9 @@ clean:
 realclean: clean
 	rm -f depend
 
-DFILES=$(hh) $(cc) $(inl) $(templatecc) Makefile Sources.make TODO README
-DDIR=$(DNAME)
+fversion.hh: Variables.make make_version
+	make_version $(MAJVER) $(MINVER) $(PATCHLEVEL) "$(CXX) `$(CXXVER)`" > $@
+
 
 dist:
 	-mkdir $(DDIR)
diff --git a/flower/Variables.make b/flower/Variables.make
new file mode 100644
index 0000000000..e0f94d6555
--- /dev/null
+++ b/flower/Variables.make
@@ -0,0 +1,19 @@
+MAJVER=1
+MINVER=0
+PATCHLEVEL=14
+
+PACKAGENAME=flower
+VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
+DNAME=$(PACKAGENAME)-$(VERSION)
+DEFINES=-DNDEBUG -O2
+#DEFINES=-g
+CXXFLAGS+=$(DEFINES)  -Wall -W -pedantic
+CXXVER=$(CXX) --version
+include Sources.make
+
+obs=$(cc:.cc=.o)
+staticlib=libflower.a
+
+DFILES=$(hh) $(cc) $(inl) $(templatecc) Makefile Variables.make make_version\
+	Sources.make TODO README
+DDIR=$(DNAME)
diff --git a/flower/assoc.hh b/flower/assoc.hh
index 2409985668..3a49c8a058 100644
--- a/flower/assoc.hh
+++ b/flower/assoc.hh
@@ -4,7 +4,7 @@
 #include "vray.hh"
 #include <assert.h>
 
-template<class K,class V>
+template<class K, class V>
 struct Assoc_ent_ {
     bool free;
     K key;
@@ -69,7 +69,6 @@ public:
 	assert(elt_query(key));
 	return arr[find(key)].val;
     }
-
 };
 /** mindblowingly stupid Associative array implementation
  */
diff --git a/flower/cursor.hh b/flower/cursor.hh
index 6bd4e1895d..6d40bb270d 100644
--- a/flower/cursor.hh
+++ b/flower/cursor.hh
@@ -82,7 +82,7 @@ class Cursor
     void del();
     
     /// access the list this came from
-    const List<T>& list() const ;
+    List<T>& list() const ;
     Link<T>* pointer();
 
 private:
diff --git a/flower/cursor.inl b/flower/cursor.inl
index 4337ef446a..278d865bff 100644
--- a/flower/cursor.inl
+++ b/flower/cursor.inl
@@ -55,7 +55,7 @@ Cursor<T>::insert( const T& th )
 }
 
 template<class T>
-inline const List<T>&
+inline  List<T>&
 Cursor<T>::list() const
 {
     return list_;
diff --git a/flower/fproto.hh b/flower/fproto.hh
index 43452af7b8..8e30550696 100644
--- a/flower/fproto.hh
+++ b/flower/fproto.hh
@@ -19,9 +19,6 @@ template<class T> struct Link;
 template<class T> struct Handle ;
 
 
-struct Assoc_ent_ ;
-struct Assoc ;
-struct Assoc_iter ;
 struct Choleski_decomposition ;
 struct Interval ;
 struct long_option_init ;
diff --git a/flower/make_version b/flower/make_version
new file mode 100755
index 0000000000..f584d272a9
--- /dev/null
+++ b/flower/make_version
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+echo '#ifndef FVERSION_HH'
+echo '#define FVERSION_HH'
+
+echo '#define FMAJORVERSION ' $1
+echo '#define FMINORVERSION ' $2
+echo '#define FPATCHLEVEL ' $3
+echo '#define FVERSIONSTR "'$1.$2.$3'"'
+echo '#define FCOMPILER "'$4'"'
+echo '#endif'
diff --git a/flower/plist.hh b/flower/plist.hh
index 19db901f8a..99be3ff811 100644
--- a/flower/plist.hh
+++ b/flower/plist.hh
@@ -28,7 +28,7 @@ class PointerList : public List<void *>
 ///  pl. which deletes pointers given to it.
 template<class T>
 struct IPointerList : public PointerList<T> {
-    IPointerList(IPointerList&) { set_empty(); }
+    IPointerList(const IPointerList&) { set_empty(); }
     IPointerList() { }
 protected:
     virtual void remove( Cursor<void*> me ) { remove (PCursor<T>(me)); }
diff --git a/hdr/clef.hh b/hdr/clef.hh
index 52206960ed..243ea6ebdd 100644
--- a/hdr/clef.hh
+++ b/hdr/clef.hh
@@ -6,7 +6,7 @@
 
 #ifndef CLEF_HH
 #define CLEF_HH
-#include "string.hh"
+#include "scalar.hh"
 #include "vray.hh"
 
 struct Clef {
@@ -14,7 +14,7 @@ struct Clef {
     String clef_type;
 
     Clef();
-    void read(svec<String> args);    
+    void read(svec<Scalar> args);    
 };
 #endif // CLEF_HH
 
diff --git a/hdr/command.hh b/hdr/command.hh
index e13669f46c..e2ece4a6fa 100644
--- a/hdr/command.hh
+++ b/hdr/command.hh
@@ -3,7 +3,7 @@
 
 #include "glob.hh"
 #include "vray.hh"
-#include "string.hh"
+#include "scalar.hh"
 
 enum Commandcode {
 	NOP,
@@ -18,7 +18,7 @@ struct Command {
 
     Real when;
     /// analogous to argv[]
-    svec<String> args;
+    svec<Scalar> args;
 
     ///
     int priority;
diff --git a/hdr/getcommand.hh b/hdr/getcommand.hh
index b1af2699e2..eb6f624966 100644
--- a/hdr/getcommand.hh
+++ b/hdr/getcommand.hh
@@ -1,8 +1,16 @@
-Command*get_clef_interpret_command(String w);
-Command *get_bar_command(Real);
-Command* get_meterchange_command( int,int);
+/*
+  getcommand.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef GETCOMMAND_HH
+#define GETCOMMAND_HH
+#include "proto.hh"
+
+
 Command* get_meter_command( Real,int,int);
-Command* get_skip_command( int,Real);
-Command* get_key_interpret_command(svec<String>);
-Command *get_reset_command();
-Command*get_partial_command(Real u);
+
+
+
+#endif // GETCOMMAND_HH
diff --git a/hdr/identifier.hh b/hdr/identifier.hh
index f1d99678d9..c5d7a5b5b7 100644
--- a/hdr/identifier.hh
+++ b/hdr/identifier.hh
@@ -7,30 +7,21 @@
 
 #ifndef IDENTIFIER_HH
 #define IDENTIFIER_HH
-#include "proto.hh"
-#include "string.hh"
-
-struct Identifier
-{
-    void *data;
-    String name;
-    
-    Identifier(String n) ;
-    virtual ~Identifier();
-    virtual Staff * staff() { assert(false); }
-    virtual Voice_list * voices() { assert(false); }
-};
-
-struct Staff_id : Identifier {
-    Staff_id(String s, Staff*st):Identifier(s) { data = st; }
-    virtual Staff* staff() { return (Staff*) data; }
-    ~Staff_id();
-};
-
-struct Voices_id : Identifier {
-    Voices_id(String s, Voice_list*st):Identifier(s) { data = st; }
-    virtual Voice_list * voices() { return (Voice_list*)data; }
-    ~Voices_id();
-};
+#include "identparent.hh"
+#include "inputstaff.hh"
+#include "inputmusic.hh"
+
+#define make_id_class(Idclass, Class, accessor)	\
+struct Idclass : Identifier {\
+    Idclass(String s, Class*st):Identifier(s) { data = st; }\
+    virtual Class* accessor() { return (Class*) data; }\
+    ~Idclass() { delete accessor(); }\
+}\
+
+
+make_id_class(Staff_id, Input_staff, staff);
+make_id_class(M_chord_id, Music_general_chord, mchord);
+make_id_class(M_voice_id, Music_voice, mvoice);
+
 #endif // IDENTIFIER_HH
 
diff --git a/hdr/identparent.hh b/hdr/identparent.hh
new file mode 100644
index 0000000000..d8d3cb1735
--- /dev/null
+++ b/hdr/identparent.hh
@@ -0,0 +1,30 @@
+/*
+  identparent.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef IDENTPARENT_HH
+#define IDENTPARENT_HH
+
+#include "proto.hh"
+#include "string.hh"
+
+struct Identifier
+{
+    void *data;
+    String name;
+    
+    Identifier(String n) : name(n) { }
+    virtual ~Identifier() {}
+    virtual Input_staff * staff() { assert(false); }
+    virtual Voice_list * voices() { assert(false); }
+    virtual Horizontal_music*hmusic() { assert(false); }
+    virtual Vertical_music*vmusic() { assert(false); }
+    virtual Music_voice *mvoice() { assert(false); }
+    virtual Music_general_chord *mchord() { assert(false); }    
+};
+#endif // IDENTPARENT_HH
+
+
+
diff --git a/hdr/inputcommand.hh b/hdr/inputcommand.hh
new file mode 100644
index 0000000000..aeec3b8ad3
--- /dev/null
+++ b/hdr/inputcommand.hh
@@ -0,0 +1,38 @@
+/*
+  inputcommand.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef INPUTCOMMAND_HH
+#define INPUTCOMMAND_HH
+#include "proto.hh"
+#include "scalar.hh"
+#include "vray.hh"
+
+
+struct Input_command {
+    Real when;
+    
+    /// analogous to argv[]
+    svec<Scalar> args;
+    void print()const;
+    Input_command();
+    Input_command(Real);
+    operator Command();
+};
+
+Input_command* get_meterchange_command( int,int);
+Input_command* get_key_interpret_command(svec<String>);
+Input_command* get_clef_interpret_command(String w);
+Input_command *get_reset_command();
+Input_command *get_partial_command(Real u);
+Input_command* get_skip_command( int,Real);
+
+void
+interpret_meter(Input_command *c, int &beats_per_meas, int& one_beat,
+		Real& whole_per_measure);
+
+Input_command *get_bar_command(Real );
+#endif // INPUTCOMMAND_HH
+
diff --git a/hdr/inputcommands.hh b/hdr/inputcommands.hh
index 8222f9b74f..083c830aa9 100644
--- a/hdr/inputcommands.hh
+++ b/hdr/inputcommands.hh
@@ -11,7 +11,8 @@
 #include "plist.hh"
 #include "real.hh"
 
-struct Input_cursor : public PCursor<Command*>
+
+struct Input_cursor : public PCursor<Input_command*>
 {
     /// current measure info
     Real whole_per_measure;
@@ -24,22 +25,22 @@ struct Input_cursor : public PCursor<Command*>
     
     int bars;
     
-    Input_cursor(PCursor<Command*>);
+    Input_cursor(PCursor<Input_command*>);
     /// hmm. not safe. Should rethink cursor.
     void operator++(int);
     /** warning: no optor -- () defined.. */
     void reset();
     Real when()const;
-    void add(Command*);
+    void add(Input_command*);
     void setpartial(Real);
-    void addbot(Command*);
+    void addbot(Input_command*);
     void sync();
     void print()const;   
     void last_command_here();
 };
 
 /// the list of commands in Score
-struct Input_commands : public IPointerList<Command*> {
+struct Input_commands : public IPointerList<Input_command*> {
     Input_cursor ptr;
 
     /****************/
@@ -50,7 +51,7 @@ struct Input_commands : public IPointerList<Command*> {
     
     Input_commands();
     Input_commands(Input_commands const&);
-    void add(Command*);
+    void add(Input_command);
     void reset();
     void print()const;
     Staff_commands *parse() const;
@@ -58,7 +59,7 @@ struct Input_commands : public IPointerList<Command*> {
 
 
 void
-interpret_meter(Command *c, int &beats_per_meas, int& one_beat,
+interpret_meter(Input_command *c, int &beats_per_meas, int& one_beat,
 		Real& whole_per_measure);
 #endif // INPUTCOMMANDS_HH
 
diff --git a/hdr/inputmusic.hh b/hdr/inputmusic.hh
index d5bf580fc6..d33e157fe8 100644
--- a/hdr/inputmusic.hh
+++ b/hdr/inputmusic.hh
@@ -21,59 +21,71 @@ struct Vertical_music {
     virtual Voice_list convert()=0;
     virtual Real length()=0;
     virtual void translate_time(Real dt)=0;
+    virtual Vertical_music *clone() const = 0;
+    virtual ~Vertical_music() {}
+    virtual void print() const =0;
 };
 
 struct Horizontal_music {
     virtual Voice_list convert()=0;
     virtual Real length()=0;
     virtual void translate_time(Real dt)=0;
-};
-
-struct Horizontal_simple : Horizontal_music {
-    Voice * voice_;
-    
-    /****************/
-
-    Horizontal_simple();
-    void set(Voice*);
-    virtual Real length();
-    virtual Voice_list convert();
-    virtual void translate_time(Real dt);
-
+    virtual Horizontal_music *clone() const = 0;
+    virtual ~Horizontal_music() {}
+    virtual void print() const =0;
 };
 
 struct Vertical_simple : Vertical_music {
-    Voice * voice_;
+    Voice * voice_;		// should be a  real member
     
     /****************/
+    Vertical_simple(Vertical_simple const&);
     Vertical_simple();
+    ~Vertical_simple();
     void add(Voice_element*);
     virtual Vertical_simple*simple() { return this; }
     virtual Real length();
     virtual Voice_list convert();
     virtual void translate_time(Real dt);
+    virtual Vertical_music *clone() const {
+	return new Vertical_simple(*this);
+    }
+    virtual void print() const ;
 };
 
 struct Music_voice : Horizontal_music {
-    PointerList<Vertical_music*> voice_ ;
+    IPointerList<Vertical_music*> voice_ ;
     
     /****************/
-
+    Music_voice() {}
+    Music_voice(Music_voice const&);
     Real length();
     void add(Vertical_music*);
     void add(Voice_element*);
     virtual Voice_list convert();
     virtual void translate_time(Real dt);
+    virtual Horizontal_music *clone() const {
+	return new Music_voice(*this);
+    }
+    void concatenate(Music_voice*);
+    virtual void print() const ;
 };
 
 struct Music_general_chord : Vertical_music {
-    PointerList<Horizontal_music*> chord_;
+    IPointerList<Horizontal_music*> chord_;
 
     /****************/
+    Music_general_chord() {}
+    Music_general_chord(Music_general_chord const&s);
     void add(Horizontal_music*);
     virtual Real length();
     virtual Voice_list convert();
     virtual void translate_time(Real dt);
+    virtual Vertical_music *clone() const {
+	return new Music_general_chord(*this);
+    }
+    void concatenate(Music_general_chord*);
+    virtual void print() const ;
 };
 
 
diff --git a/hdr/inputscore.hh b/hdr/inputscore.hh
new file mode 100644
index 0000000000..a34e6d9579
--- /dev/null
+++ b/hdr/inputscore.hh
@@ -0,0 +1,29 @@
+#ifndef ISCORE_HH
+#define ISCORE_HH
+#include "vray.hh"
+#include "proto.hh"
+#include "plist.hh"
+
+
+/// the total music def of one movement
+struct Input_score {
+    /// paper_, staffs_ and commands_ form the problem definition.
+    Paperdef *paper_;
+    IPointerList<Input_staff*> staffs_;
+    IPointerList<Input_command*> commands_;
+    
+    /****************************************************************/
+    Input_score();
+    Input_score(Input_score&);
+    void add(svec<Input_command*> &s);
+    void add(Input_staff*);
+    ~Input_score();
+    /// construction
+    void set(Paperdef*);
+    void print() const;
+    Score*parse();
+};
+/**
+        
+    */
+#endif
diff --git a/hdr/inputstaff.hh b/hdr/inputstaff.hh
new file mode 100644
index 0000000000..abfcc52f61
--- /dev/null
+++ b/hdr/inputstaff.hh
@@ -0,0 +1,33 @@
+/*
+  inputstaff.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef INPUTSTAFF_HH
+#define INPUTSTAFF_HH
+
+#include "string.hh"
+#include "plist.hh"
+#include "vray.hh"
+#include "proto.hh"
+
+struct Input_staff {
+    String type;
+    IPointerList<Input_command*> commands_;
+    IPointerList<Horizontal_music*> music_;
+
+    /****************/
+
+    void add(Horizontal_music*m);
+    Input_staff(Input_staff&);
+    Input_staff(String);
+    void add(svec<Input_command*> &s);
+    Staff* parse(PointerList<Input_command*>);
+    void print() const;
+ 
+};
+
+
+#endif // INPUTSTAFF_HH
+
diff --git a/hdr/key.hh b/hdr/key.hh
index c65beea636..f0141d688f 100644
--- a/hdr/key.hh
+++ b/hdr/key.hh
@@ -8,7 +8,7 @@
 #define KEY_HH
 
 #include "vray.hh"
-#include "string.hh"
+#include "scalar.hh"
 
 class Key {
     svec<int> accidentals;
@@ -16,8 +16,8 @@ class Key {
     /****************/
 
 public:
-    svec<int> read(svec<String> );
-    svec<int> oldkey_undo(svec<String>);
+    svec<int> read(svec<Scalar> );
+    svec<int> oldkey_undo(svec<Scalar>);
 
     Key();
     void set(int i, int acc);
diff --git a/hdr/lookup.hh b/hdr/lookup.hh
index 29b4aa9c5b..90a27fd60f 100644
--- a/hdr/lookup.hh
+++ b/hdr/lookup.hh
@@ -6,6 +6,8 @@
 
 #include "symbol.hh"
 #include "fproto.hh"
+#include "scalar.hh"
+
 struct Lookup {
     Symtables *symtables_;
     
@@ -24,7 +26,7 @@ struct Lookup {
       pos == -3: below staff
       */
 
-    Symbol meter(svec<String>);
+    Symbol meter(svec<Scalar>);
     Symbol stem(Real y1_pos, Real y2_pos);
     Symbol rule_symbol(Real height, Real width);
     Symbol accidental(int);
diff --git a/hdr/main.hh b/hdr/main.hh
index 5bd2a545f2..f5a795a951 100644
--- a/hdr/main.hh
+++ b/hdr/main.hh
@@ -5,7 +5,7 @@
 void debug_init();
 void set_debug(bool);
 void do_scores();
-void add_score(Score * s);
+void add_score(Input_score * s);
 void set_default_output(String s);
 const char *get_version();
 
diff --git a/hdr/melodicstaff.hh b/hdr/melodicstaff.hh
index c908f1dcb0..733eae3fef 100644
--- a/hdr/melodicstaff.hh
+++ b/hdr/melodicstaff.hh
@@ -17,7 +17,7 @@ struct Melodic_staff : public Simple_staff
 
     virtual Rest *get_rest(Rest_req *rq);
     virtual void set_output(PScore *);
-    virtual Melodic_staff*clone()const;
+
     virtual Item* get_TYPESET_item(Command*);
     virtual Stem * get_stem(Stem_req *rq);
     virtual Notehead * get_notehead(Note_req *rq, int bot);
diff --git a/hdr/meter.hh b/hdr/meter.hh
index 5498112d37..a9db9c100a 100644
--- a/hdr/meter.hh
+++ b/hdr/meter.hh
@@ -10,9 +10,9 @@
 #include "vray.hh"
 
 struct Meter: Item {
-    svec<String> args;
+    svec<Scalar> args;
     
-    Meter(svec<String> args) ;
+    Meter(svec<Scalar> args) ;
     void preprocess();
 };
 #endif // METER_HH
diff --git a/hdr/pcol.hh b/hdr/pcol.hh
index f6a38d57aa..1f3e15df3f 100644
--- a/hdr/pcol.hh
+++ b/hdr/pcol.hh
@@ -37,7 +37,8 @@ struct PCol {
     PScore * pscore_;
 
     /****************/
-
+    /// which  one (left =0)
+    int rank() const;
     /// does this column have items, does it have spacings attached?
     bool used() const;
     
diff --git a/hdr/proto.hh b/hdr/proto.hh
index 065424b7c9..5f93591147 100644
--- a/hdr/proto.hh
+++ b/hdr/proto.hh
@@ -86,5 +86,7 @@ struct Horizontal_simple;
 struct Vertical_simple ;
 struct Music_voice;
 struct Music_general_chord;
-
+struct Input_score;
+struct Input_staff;
+struct Input_command;
 #endif // PROTO_HH
diff --git a/hdr/rhythmstaff.hh b/hdr/rhythmstaff.hh
index b402584fde..2c099afa0b 100644
--- a/hdr/rhythmstaff.hh
+++ b/hdr/rhythmstaff.hh
@@ -19,7 +19,6 @@ struct Rhythmic_staff : public Simple_staff
     virtual Stem *get_stem(Stem_req *rq);
     virtual Notehead * get_notehead(Note_req *rq, int b);   
     virtual void set_output(PScore *);
-    virtual Rhythmic_staff*clone()const;
 };
 
 #endif // RHYTHMSTAF_HH
diff --git a/hdr/sccol.hh b/hdr/sccol.hh
index f8aceb2304..b61a02682f 100644
--- a/hdr/sccol.hh
+++ b/hdr/sccol.hh
@@ -29,6 +29,8 @@ struct Score_column {
     static int compare(Score_column & c1, Score_column &c2) {
 	return sgn(c1.when - c2.when);
     }
+    void add_duration(Real );
+    void preprocess();
     void set_breakable() {
 	 pcol_->set_breakable();
     }
diff --git a/hdr/score.hh b/hdr/score.hh
index 20a4d75da8..fbcfde1fc0 100644
--- a/hdr/score.hh
+++ b/hdr/score.hh
@@ -10,20 +10,15 @@ struct Score {
     /// paper_, staffs_ and commands_ form the problem definition.
     Paperdef *paper_;
     IPointerList<Staff*> staffs_;
-
-    svec<Command*> input_commands_;
     
     /// "runtime" fields for setting up spacing    
     IPointerList<Score_column*> cols_;
     PScore *pscore_;
 
     /****************************************************************/
-    void add(svec<Command*> &s);
- 
+
     /// construction
-    void add_staff(Staff *st);
-    void set(Paperdef*);
-    Score();
+    Score(Paperdef*);
     ~Score();    
     void add(Staff*);        
 
diff --git a/hdr/staff.hh b/hdr/staff.hh
index 803bf87388..9f1ba1f498 100644
--- a/hdr/staff.hh
+++ b/hdr/staff.hh
@@ -19,13 +19,10 @@ struct Staff {
     Score *score_;
     PScore *pscore_;
 
-    svec<Command*> input_commands_;
-        
     /****************************************************************/
-    void add(svec<Command*> &s);
     void add(PointerList<Voice*> &s);
-    void process_input_commands(svec<Command*> &s, Real l);
-    
+    void process_commands(Real l);
+
     Staff(const Staff&src);
     void add_voice(Voice *v);
     void add_staff_column(Staff_column *sp);
@@ -45,13 +42,11 @@ struct Staff {
     Staff_column * get_col(Real,bool);
 
     Staff();
-    /**
-      Should construct with Score as arg, but this isn't known during parsing.      
-      */
+
     /****************************************************************
       VIRTUALS
     ****************************************************************/
-    virtual Staff*clone()const=0;    
+
     virtual void set_output(PScore * destination)=0;
     virtual void walk()=0;    
     virtual Staff_column * create_col(Score_column * )=0;
diff --git a/hdr/stcol.hh b/hdr/stcol.hh
index 17469a4db5..a620f8795d 100644
--- a/hdr/stcol.hh
+++ b/hdr/stcol.hh
@@ -26,6 +26,7 @@ struct Staff_column {
     bool mus() const;
     Real when() const;
     void add(Voice_element*ve);
+
     /****************************************************************
       VIRTUAL
     ****************************************************************/
diff --git a/hdr/tex.hh b/hdr/tex.hh
index 546797a7c1..aba60f06c4 100644
--- a/hdr/tex.hh
+++ b/hdr/tex.hh
@@ -3,6 +3,7 @@
 
 #include "string.hh"
 #include "boxes.hh"
+#include "scalar.hh"
 
 /// parameter substitution in TeXstrings
 String
@@ -14,6 +15,10 @@ substitute_args(String source, svec<String> args);
   eval({"X","Y"})  == "texXblaY"
   */
 
+/// parameter substitution in TeXstrings
+String
+substitute_args(String source, svec<Scalar> args);
+
 /// #h# is in points
 String vstrut(Real h);
 
diff --git a/kortjakje.ly b/kortjakje.ly
index 86835bf3b5..967d2632c1 100644
--- a/kortjakje.ly
+++ b/kortjakje.ly
@@ -2,16 +2,16 @@
 % 
 % bare bones version. (written down from memory :-)
 
-melodie = $ \octave {c}
+melodie = music {$ \octave {c}
 	%%% theme
 	  c c g g	a a	g2	f f	e e	d d  c2
 	  g g	f f	e e 	d d	g g	f f	e e 	d d
  	%%% var 1
 	  c r8 c8 (	) g r8 g8 (	) a r8 a8 (	) g r4 
 	  f r8 f8 (	) e4 r8 e8 (	) d4 r8 d8 (	) c4 r4
-$
+$}
 
-begeleiding = $
+begeleiding = $\music {
 	\octave {`c}
 	%%% theme
 	`c c	e c	f c	e c	d `b	c `a	`f `g	`c2
@@ -20,17 +20,19 @@ begeleiding = $
 	%%%% var 1
 	r8 e8() c  	r8 e8() c  	r8 f8()c 	r8 e8()c
 	r8 d8()`b 	r8 c8()`a 	r8 `a8()`f 	r8 `e8()`c
-$
+}$
 
 
-bstaf = melodicstaff {
-		voices { begeleiding }
+bstaf = staff {
+	melodic
+	music { begeleiding }
 		commands {
 			clef bass
 		}
 	}
-vstaf = melodicstaff {
-		voices { melodie }
+vstaf = staff {
+	melodic
+		music { melodie }
 	}
 
 
@@ -38,7 +40,7 @@ score {
 	staff { vstaf }
 	staff { bstaf }
 	paper {
-%		unitspace 2.5cm
+		unitspace 2.5cm
 	}
 	commands {
 		meter 2 4 
diff --git a/maartje.ly b/maartje.ly
index c1dd45a689..5178885f0f 100644
--- a/maartje.ly
+++ b/maartje.ly
@@ -1,27 +1,27 @@
-ritme = rhythmstaff {
-	$
+ritme = staff {rhythmic
+	music {$
 	c8 c2 c2
 	%[c8( )'a8 c8 c8]
 	c2 c2
 	
 	[fis16 'dis16( fis16 'dis16 ][fis16) 'dis16 fis16 'dis16]
-	c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $
+	c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $}
 }
 
 melody=
-melodicstaff {
-	$
+staff { melodic
+	music{$
 	c8
 	r1
 	'cis2..	r8
 	r4 r8 r16 r32 r32 
 
 	\duration {4}  \chord {
-		\voice { c () `bes c}
-		\voice {'fis ()'gisis fis }
-		\voice { d () d dis }
-		\voice {  a  () bes eis }
-		\voice { fis () g gis }
+		\music { c () `bes c}
+		\music { 'fis ()'gisis fis }
+		\music { d () d dis }
+		\music {  a  () bes eis }
+		\music { fis () g gis }
 	}
 	c4
 
@@ -30,10 +30,10 @@ melodicstaff {
 	a8 b8 'c8 'd8 ''c8 ```c8 c4 c4  c4 c4
 	\duration{ 16 } `b `a `g `f \duration{ 4}
 	c `b `a `g `f `e `d `c ``b ``a ``g ``f ``e ``d ``c
-	$
+	$}
 
-
-commands {
+	commands {
+	skip 0:0.125
 	skip 2:0
 	key $ fis cis gis $
 	skip 2:0
@@ -52,9 +52,8 @@ score {
 	staff { melody }
 %	staff { melody }
 	commands {
-		partial 0.125 skip 0:0.125
-
 		meter 4 4
+		partial 0.125 skip 0:0.125
 		skip 2:0		
 		meter 2 4
 		skip 19:0
diff --git a/pavane.ly b/pavane.ly
index e58508cb98..529ffce943 100644
--- a/pavane.ly
+++ b/pavane.ly
@@ -1,12 +1,13 @@
 % pavane pour une Infante d\'efunte
 % 
-% M. Ravel
+% Maurice Ravel
 %
 % (Ravel has been dead for over 50 years. This does not have copyright)
 %
 
-horn = melodicstaff {
-	$
+horn =
+staff {melodic
+	music{ 	$
 	\octave { 'c }
 	\duration { 8}
 
@@ -21,11 +22,11 @@ horn = melodicstaff {
 	cis4 d4()[d cis d e]
 \octave { c }
 					a4 gis2.
-	a4 b4()[b a b cis]		fis4 e4 cis2
+	a4 b4()[b a b 'cis]		fis4 e4 cis2
 	e4 fis4 () [fis e fis gis]	cis4 `b4()`b8 r8 r4
 
 	r4 r4 				'cis4 'd4 () ['d 'cis 'd 'e]
-	a4 gis2.			a4 b4()[b a b cis]
+	a4 gis2.			a4 b4()[b a b 'cis]
 	fis4 e4 cis2			e4 fis4()[fis e fis gis]
 	cis4 `b4()`b8 r8 r4		r1
 	r2 r4 r4			
@@ -37,16 +38,19 @@ horn = melodicstaff {
 	r4 fis2 fis4 			fis2()[fis e a fis]
 	fis4 e4 d4 e4 			`b2() [`b `a d cis]
 	`b [`fis `a `b] cis4 `b4	`fis2 r2
-	$
-	commands {
+	$}
+	commands {	
 		key  $fis cis $
 	}
 }
 
 score {
-	staff { horn }
-	paper { unitspace 2.2 cm
-		geometric 1.5
+	staff {
+		horn
+	}
+	paper {
+		unitspace 1.5 cm
+		geometric 1.4
 	}
 	commands { meter 4 4
 		skip 18:0
diff --git a/src/beam.cc b/src/beam.cc
index 6eb4d07813..af61c10ad2 100644
--- a/src/beam.cc
+++ b/src/beam.cc
@@ -7,6 +7,7 @@
 #include "stem.hh"
 #include "paper.hh"
 #include "lookup.hh"
+#include "scalar.hh"
 
 
 struct Stem_info {
diff --git a/src/calcideal.cc b/src/calcideal.cc
index 3f9a7dca23..47ca885ade 100644
--- a/src/calcideal.cc
+++ b/src/calcideal.cc
@@ -24,12 +24,10 @@ Score::do_connect(PCol *c1, PCol *c2, Real d, Real h)
 void
 Score::connect(PCol* c1, PCol *c2, Real d, Real h)
 {
-    if (c2->used() && c1->used()) {
-	do_connect(c1,c2,d,h);
-	do_connect(c1->postbreak, c2,d,h);
-	do_connect(c1, c2->prebreak,d,h);
-	do_connect(c1->postbreak, c2->prebreak,d,h);
-    }
+    do_connect(c1,c2,d,h);
+    do_connect(c1->postbreak, c2,d,h);
+    do_connect(c1, c2->prebreak,d,h);
+    do_connect(c1->postbreak, c2->prebreak,d,h);
 }
 
 /* this needs A LOT of rethinking.
@@ -39,43 +37,61 @@ Score::connect(PCol* c1, PCol *c2, Real d, Real h)
 void
 Score::calc_idealspacing()
 {
+#if 1
     PCursor<Score_column*> i(cols_);
 
     for (; i.ok(); i++) {
-		
+	assert(i->used());
 	PCursor<Score_column*> j (i+1);
 	if (i->musical) {
 	    for (int n=0; n < i->durations.sz(); n++) {
 		Real d = i->durations[n];
 		Real dist = paper_->duration_to_dist(d);
-		while (d + i->when > j->when)
+		while (j->when < d + i->when)
 		    j++;
+		
+		assert(j->when == d+i->when);
 
-		if (j->used())
-		    connect(i->pcol_, j->pcol_, dist);
-		if (!j->musical && (j+1)->used && (j+1)->when == j->when) {
+		connect(i->pcol_, j->pcol_, dist);
+		if (!j->musical && (j+1).ok() 
+		    && (j+1)->when == j->when) {
 		    j++;
 		    connect(i->pcol_, j->pcol_,  dist);
 		}
 	    }
-	} else if (i->used()) {
-
+	} else if (j.ok()) {
+	    
 	    /* attach i to the next column in use. This exists, since
 	      the last col is breakable, and therefore in use
 	      */
-	    for (;j.ok(); j++) {
-		if (j->used()) {
-		    Real d = j->when - i->when;
-		    Real dist = (d) ? paper_->duration_to_dist(d) :
-			convert_dimen(2,"pt");
+	    
+	    Real d = j->when - i->when;
+	    Real dist = (d) ? paper_->duration_to_dist(d) :
+		convert_dimen(2,"pt");
+	    
+	    connect(i->pcol_, j->pcol_, dist, (d) ? 1.0:1.0);
+	}
+	    // !j.ok() might hold if we're at the last col.
+	
+    }
+#else
+    PCursor<Score_column*> sc(cols_);
 
-		    connect(i->pcol_, j->pcol_, dist, (d) ? 1.0:1.0);
-		    break;
-		}
+    for (; sc.ok(); sc++) {
+	if (sc->musical)
+	    for (int i=0; i < sc->durations.sz(); i++) {
+		Real d = sc->durations[i];
+		Real dist = paper_->duration_to_dist(d);
+		PCol * c2 = find_col(sc->when + d,true)->pcol_;
+		connect(sc->pcol_, c2, dist);
+		c2 = find_col(sc->when + d,false)->pcol_;
+		connect(sc->pcol_, c2,  dist);
 	    }
-	    // !j.ok() might hold if we're at the last col.
+	else if (sc->used()) {	// ignore empty columns
+	    PCol * c2 = find_col(sc->when,true)->pcol_;
+	    connect(sc->pcol_, c2, 0.0);
 	}
-    }       	
+#endif
 }
 
 
diff --git a/src/clef.cc b/src/clef.cc
index d12225e8d6..49671dd426 100644
--- a/src/clef.cc
+++ b/src/clef.cc
@@ -7,7 +7,7 @@ Clef::Clef()
 }
 
 void
-Clef::read(svec<String> args)
+Clef::read(svec<Scalar>args)
 {
     clef_type = args[0];
     if (clef_type == "violin") {
diff --git a/src/getcommands.cc b/src/getcommands.cc
index c3b6bba692..5b12009ff9 100644
--- a/src/getcommands.cc
+++ b/src/getcommands.cc
@@ -1,28 +1,10 @@
 #include "string.hh"
+#include "inputcommand.hh"
 #include "parseconstruct.hh"
 #include "command.hh"
 
 Command*
-get_partial_command(Real u)
-{
-    Command*c = new Command;
-    c->code = INTERPRET;    
-    c->args.add("PARTIAL");
-    c->args.add(u);
-    return c;
-}
-
-Command*
-get_reset_command()
-{
-    Command*c = new Command;
-    c->code = INTERPRET;    
-    c->args.add("RESET");
-    return c;
-}
-
-Command*
-get_key_interpret_command(svec<String> which)
+get_key_interpret_command(svec<Scalar> which)
 {
     Command*c = new Command;
     c->code = INTERPRET;    
@@ -34,18 +16,7 @@ get_key_interpret_command(svec<String> which)
 }
 
 Command*
-get_clef_interpret_command(String w)
-{
-    Command*c = new Command;
-    c->code = INTERPRET;
-    c->args.add("CLEF");
-    c->args.add(w);
-    c->priority = 190;
-    return c;
-}
-
-Command*
-get_key_typeset_command(svec<String> which)
+get_key_typeset_command(svec<Scalar>which)
 {
     Command*c = new Command;
     c->code = TYPESET;    
@@ -56,19 +27,6 @@ get_key_typeset_command(svec<String> which)
     return c;
 }
 
-Command *
-get_meterchange_command(int n, int m)
-{
-    Command*c = new Command;
-
-    c->code = INTERPRET;
-    c->args.add( "METER");
-    c->args.add( n );
-    c->args.add( m );
-    c->priority = 170;		// more than bar
-    return c;
-}
-
 Command *
 get_meter_command(Real w, int n, int m)
 {
@@ -82,7 +40,7 @@ get_meter_command(Real w, int n, int m)
     c->priority = 40;
     return c;
 }
-
+#if 0
 Command*
 get_bar_command(Real w)
 {
@@ -96,17 +54,4 @@ get_bar_command(Real w)
 }
 
 
-Command *
-get_skip_command(int n, Real m)
-{
-    Command*c = new Command;
-    
-    c->code = INTERPRET;
-    c->args.add( "SKIP");
-    c->args.add( n );
-    c->args.add( m );
-    c->priority = 0;		
-    return c;
-}
-
-
+#endif
diff --git a/src/idealspacing.cc b/src/idealspacing.cc
new file mode 100644
index 0000000000..c6b84931f6
--- /dev/null
+++ b/src/idealspacing.cc
@@ -0,0 +1,30 @@
+#include "pcol.hh"
+#include "pscore.hh"
+#include "pstaff.hh"
+#include "debug.hh"
+
+void
+Idealspacing::print() const
+{
+#ifndef NPRINT
+    mtor << "idealspacing {" ;
+    mtor << "distance "<<space<< " strength " << hooke ;
+    mtor << "left " << left->rank() << " right " << right->rank() << "}\n";
+#endif
+}
+
+Idealspacing::Idealspacing(const PCol * l,const PCol * r)
+{
+    space = 0.0;
+    hooke = 0.0;
+    left = l;
+    right = r;
+}
+
+void
+Idealspacing::OK() const
+{
+#ifndef NDEBUG
+    assert(hooke >= 0 && left  && right);
+#endif    
+}
diff --git a/src/identifier.cc b/src/identifier.cc
deleted file mode 100644
index 40281ce718..0000000000
--- a/src/identifier.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <assert.h>
-#include "identifier.hh"
-#include "staff.hh"
-#include "lexer.hh"
-#include "inputmusic.hh"
-
-
-Identifier::Identifier(String n)
-    :name  (n)
-{
-    data = 0;
-}
-
-
-Identifier::~Identifier()
-{    
-}
-
-Staff_id::~Staff_id()
-{
-    delete staff();
-}
-
-Voices_id::~Voices_id()
-{
-    voices()->junk();
-    delete voices();
-}
diff --git a/src/inputcommand.cc b/src/inputcommand.cc
new file mode 100644
index 0000000000..c0bdb96919
--- /dev/null
+++ b/src/inputcommand.cc
@@ -0,0 +1,124 @@
+#include "inputcommand.hh"
+#include "debug.hh"
+#include "command.hh"
+
+Input_command::Input_command()
+{
+    when = -1;
+}
+
+Input_command::Input_command(Real w)
+{
+    when =w;
+}
+
+Input_command::operator Command()
+{
+    Command c(when);
+    if (!args.sz())
+	return c;
+    
+    c.code = INTERPRET;
+    String s = args[0];
+        
+    int p;
+    if (s == "KEY")
+	p = 200;
+    else if (s=="CLEF")
+	p = 190;
+    else if (s == "METER")
+	p = 180;
+    else if (s == "BAR")
+	p = 170;
+    
+    c.priority = p;
+    c.args = args;
+    
+    return c;    
+}
+
+
+Input_command*
+get_partial_command(Real u)
+{
+    Input_command*c = new Input_command;
+    c->args.add("PARTIAL");
+    c->args.add(u);
+    return c;
+}
+
+Input_command*
+get_key_interpret_command(svec<String>a ) 
+{
+    Input_command*c = new Input_command;
+    c->args.add("KEY");
+    for (int i=0; i < a.sz(); i ++)
+	c->args.add(a[i]);
+    
+    return c;
+}
+
+Input_command*
+get_reset_command()
+{
+    Input_command*c = new Input_command;
+    c->args.add("RESET");
+    return c;
+}
+
+Input_command *
+get_meterchange_command(int n, int m)
+{
+    Input_command*c = new Input_command;
+
+    c->args.add( "METER");
+    c->args.add( n );
+    c->args.add( m );
+
+    return c;
+}
+
+Input_command *
+get_bar_command(Real w)
+{
+    Input_command*c = new Input_command;
+    c->when = w;
+    c->args.add( "BAR");
+    c->args.add( "|");
+
+    return c;
+}
+
+Input_command *
+get_skip_command(int n, Real m)
+{
+    Input_command*c = new Input_command;
+    
+    c->args.add( "SKIP");
+    c->args.add( n );
+    c->args.add( m );
+
+    return c;
+}
+
+
+void
+Input_command::print()const
+{
+    mtor << "{ at " << when;
+    if (args.sz()) {
+	mtor<< " args: ";
+	for (int i = 0; i<args.sz(); i++)
+	    mtor << "`"<<args[i] <<"',";
+    }
+    mtor << "}\n";
+}
+
+Input_command*
+get_clef_interpret_command(String w)
+{
+    Input_command*c = new Input_command;
+    c->args.add("CLEF");
+    c->args.add(w);
+    return c;
+}
diff --git a/src/inputcommands.cc b/src/inputcommands.cc
index 2372a0ff14..457fb9a57d 100644
--- a/src/inputcommands.cc
+++ b/src/inputcommands.cc
@@ -3,6 +3,7 @@
   */
 
 #include "inputcommands.hh"
+#include "inputcommand.hh"
 #include "debug.hh"
 #include "staffcommands.hh"
 #include "getcommand.hh"
@@ -11,8 +12,8 @@
 Input_commands::Input_commands(Input_commands const&src)
     : ptr(src.ptr)
 {
-    IPointerList<Command*> &me(*this);
-    const IPointerList<Command*> &that(src);
+    IPointerList<Input_command*> &me(*this);
+    const IPointerList<Input_command*> &that(src);
     
     PL_copy(me, that);    
 }
@@ -20,8 +21,8 @@ Input_commands::Input_commands(Input_commands const&src)
 Input_commands::Input_commands()
     :    ptr (bottom())
 {
-    Command c(0.0);		
-    bottom().add(new Command(c));    
+    Input_command c(0.0);		
+    bottom().add(new Input_command(c));    
     ptr = bottom();    
 }
 
@@ -32,7 +33,7 @@ Input_commands::truncate(Real last)
     
     if (ptr.when() >= last)
 	reset_=true;
-    PCursor<Command*> i(*this);
+    PCursor<Input_command*> i(*this);
     
     while (i.ok() && i ->when < last)
 	i++;
@@ -67,11 +68,11 @@ Input_commands::find_moment(Real w)
 	    ptr.addbot(get_bar_command(bar_when));
 	    find_moment(w);	// tail-recursion. todo
 	} else {
-	    ptr.addbot(new Command(w));
+	    ptr.addbot(new Input_command(w));
 	}
 
     } else if (ptr.when() != w) {
-	ptr.insert(new Command(w));
+	ptr.insert(new Input_command(w));
 	ptr--;	
     }
 }
@@ -98,37 +99,32 @@ Input_commands::do_skip(int & bars, Real & wholes)
 
 
 void
-Input_commands::add(Command *c)
+Input_commands::add(Input_command c)
 {    
-    assert(c->code==INTERPRET);
-    if (c->args[0] == "PARTIAL") {
-	Real p = c->args[1].fvalue();
+    if (c.args[0] == "PARTIAL") {
+	Real p = c.args[1].fvalue();
 	ptr.setpartial(p);
 	
-    } else if (c->args[0] == "METER") {
+    } else if (c.args[0] == "METER") {
 	int beats_per_meas, one_beat;
 	Real r;
 	
-	interpret_meter(c, beats_per_meas, one_beat, r);
-	Command *ch = get_meterchange_command(beats_per_meas, one_beat);
+	interpret_meter(&c, beats_per_meas, one_beat, r);
+	Input_command *ch = get_meterchange_command(beats_per_meas, one_beat);
 	ch->when = ptr.when();	
 	ptr.add(ch);
-	
-	delete c;
-	
-    } else if  (c->args[0] == "KEY" || c->args[0] == "CLEF") {
-	c->when = ptr.when();
-	ptr.add(c);
-    } else if (c->args[0] == "SKIP") {
-	int bars = c->args[1].value() ;
-	Real wholes= c->args[2].fvalue();
+		
+    } else if  (c.args[0] == "KEY" || c.args[0] == "CLEF") {
+	Input_command *ic = new Input_command(c);
+	ic->when = ptr.when();
+	ptr.add(ic);
+    } else if (c.args[0] == "SKIP") {
+	int bars = c.args[1].value() ;
+	Real wholes= c.args[2].fvalue();
 	while (bars > 0 || wholes > 0.0) {
 	    do_skip(bars, wholes);
 	}
-	delete c;
-    } else if (c->args[0] == "RESET") {
-	delete c;
-	
+    } else if (c.args[0] == "RESET") {
 	reset();	
     }
     
@@ -155,8 +151,8 @@ Input_commands::parse() const
 	nc->process_add(c);
     }
 
-    for (PCursor<Command*> cc(*this); cc.ok(); cc++) {
-	if (cc->code != NOP)
+    for (PCursor<Input_command*> cc(*this); cc.ok(); cc++) {
+	if (cc->args.sz() &&  cc->args[0] !="")
 	    nc->process_add(**cc);
     }
     
diff --git a/src/inputcursor.cc b/src/inputcursor.cc
index c6f4bfbabd..4dc5f9310f 100644
--- a/src/inputcursor.cc
+++ b/src/inputcursor.cc
@@ -3,13 +3,14 @@
   */
 
 #include "inputcommands.hh"
+#include "inputcommand.hh"
 #include "debug.hh"
 #include "staffcommands.hh"
 #include "getcommand.hh"
 #include "command.hh"
 
 void
-interpret_meter(Command *c, int &beats_per_meas, int& one_beat,
+interpret_meter(Input_command *c, int &beats_per_meas, int& one_beat,
 		Real& whole_per_measure)
 {
     beats_per_meas = c->args[1].value();
@@ -41,8 +42,8 @@ Input_cursor::reset()
     last=0;    
 }
 
-Input_cursor :: Input_cursor(PCursor<Command*>c)
-    :PCursor<Command*>(c)
+Input_cursor :: Input_cursor(PCursor<Input_command*>c)
+    :PCursor<Input_command*>(c)
 {
     reset();    
 }
@@ -65,11 +66,11 @@ void
 Input_cursor::operator++(int)
 {    
     last = when();
-    (*(PCursor<Command*> *) this) ++;
+    (*(PCursor<Input_command*> *) this) ++;
 
     if (ok()) {	
 	sync();
-	if (ptr()->code == INTERPRET && ptr()->args[0] == "METER") {
+	if (ptr()->args[0] == "METER") {
 	    int i,j;	    
 	    interpret_meter(ptr(), i, j, whole_per_measure);
 	}
@@ -77,7 +78,7 @@ Input_cursor::operator++(int)
 }
 
 void
-Input_cursor::addbot(Command*c)
+Input_cursor::addbot(Input_command*c)
 {
     assert(!ok());    
     add(c);
@@ -85,9 +86,9 @@ Input_cursor::addbot(Command*c)
 
 
 void
-Input_cursor::add(Command*c)
+Input_cursor::add(Input_command*c)
 {
-    PCursor<Command*> ::add(c);
+    PCursor<Input_command*> ::add(c);
     (*this)++;
 }
 
@@ -95,7 +96,7 @@ void
 Input_cursor::last_command_here()
 {
     assert(ok());
-    PCursor<Command*> next = (*this)+1;
+    PCursor<Input_command*> next = (*this)+1;
     while (next.ok() && next->when == when()){
 	*this = next;
 	next = *this +1;
diff --git a/src/inputmusic.cc b/src/inputmusic.cc
index b00835b95d..45d00e1fb6 100644
--- a/src/inputmusic.cc
+++ b/src/inputmusic.cc
@@ -1,3 +1,4 @@
+#include "debug.hh"
 #include "inputmusic.hh"
 #include "voice.hh"
 
@@ -5,7 +6,10 @@ Vertical_simple::Vertical_simple()
 {
     voice_ = new Voice;
 }
-
+Vertical_simple::Vertical_simple(Vertical_simple const&s)
+{
+    voice_ = new Voice(*s.voice_);
+}
 void
 Vertical_simple::add(Voice_element*v)
 {
@@ -22,16 +26,51 @@ Vertical_simple::translate_time(Real t)
 {
     voice_->start += t;
 }
+
 Voice_list
 Vertical_simple::convert()
 {
     Voice_list l;
-    l.bottom().add(voice_);
+    l.bottom().add(new Voice(*voice_));
     return l;
 }
 
-    
+Vertical_simple::~Vertical_simple()
+{
+    delete voice_;
+}
+
+void
+Vertical_simple::print() const
+{
+    mtor << "Vertical_simple {";
+    voice_->print();
+    mtor << "}\n";
+}
+
 /****************/
+void
+Music_voice::print() const
+{
+     mtor << "Music_voice {";
+    for (PCursor<Vertical_music*> i(voice_); i.ok(); i++)
+	 i->print();
+    mtor << "}\n";
+}
+
+void
+Music_voice::concatenate(Music_voice*h)
+{
+    for (PCursor<Vertical_music*> i(h->voice_); i.ok(); i++)
+	add(i->clone());    
+}
+
+
+Music_voice::Music_voice(Music_voice const&s)
+{
+    for (PCursor<Vertical_music*> i(s.voice_); i.ok(); i++)
+	add(i->clone());
+}
 
 void
 Music_voice::add(Voice_element*v)
@@ -51,7 +90,6 @@ Music_voice::add(Voice_element*v)
 void
 Music_voice::add(Vertical_music*v)
 {
-    //   v->translate_time(length());
     voice_.bottom().add(v);
 }
 
@@ -73,7 +111,7 @@ Music_voice::convert()
     Real here = 0.0;
     
     for (PCursor<Vertical_music*> i(voice_); i.ok(); i++) {
-	Real len = i->length();	// has to be stored, since translate_time doesn't work on copies of the contents of i.
+	Real len = i->length();	
 	Voice_list k(i->convert());
 	k.translate_time(here);	
 	l.concatenate(k);
@@ -93,6 +131,21 @@ Music_voice::translate_time(Real t)
     
     
 /****************/
+void
+Music_general_chord::print() const
+{
+    mtor << "Music_general_chord {";
+     for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++)
+	i->print();
+     mtor << "}\n";
+}
+
+void
+Music_general_chord::concatenate(Music_general_chord*v)
+{
+    for (PCursor<Horizontal_music*> i(v->chord_); i.ok(); i++)
+	add(i->clone());
+}
 
 void
 Music_general_chord::translate_time(Real t)
@@ -130,6 +183,15 @@ Music_general_chord::convert()
     return l;
 }
 
+
+Music_general_chord::Music_general_chord(
+    Music_general_chord const & s)
+{
+    for (PCursor<Horizontal_music*> i(s.chord_); i.ok(); i++) {
+	add(i->clone());
+    }
+}
+    
 /****************/
 
 void
diff --git a/src/inputscore.cc b/src/inputscore.cc
new file mode 100644
index 0000000000..89ec2bd4e9
--- /dev/null
+++ b/src/inputscore.cc
@@ -0,0 +1,61 @@
+#include "debug.hh"
+#include "inputcommand.hh"
+#include "inputscore.hh"
+#include "inputstaff.hh"
+#include "score.hh"
+#include "paper.hh"
+
+void
+Input_score::add(svec<Input_command*> &s)
+{
+    commands_.bottom().add(get_reset_command());
+    for (int i=0; i < s.sz(); i++)
+	commands_.bottom().add(s[i]);
+}
+
+void
+Input_score::add(Input_staff*s)
+{
+    staffs_.bottom().add(s);
+}
+
+void
+Input_score::set(Paperdef*p)
+{
+    delete paper_;
+    paper_ = p;
+}
+
+Score*
+Input_score::parse()
+{
+    Paperdef* p=new Paperdef(*paper_);
+    Score *s = new Score(p);
+    
+    for (PCursor<Input_staff*> i(staffs_); i.ok(); i++) {
+	Staff* staf=i->parse(commands_);
+	s->add(staf);
+    }
+    return s;
+}
+
+Input_score::~Input_score()
+{
+    // should fix paper/symtabs to allow this deletion.
+//    delete paper_;
+}
+
+Input_score::Input_score()
+{
+    paper_=new Paperdef;
+}
+
+void
+Input_score::print()const
+{
+    mtor << "Input_score {\n";
+    for (PCursor<Input_staff*> i(staffs_); i.ok(); i++) {
+	i->print();
+    }
+    mtor << "}\n";
+}
diff --git a/src/inputstaff.cc b/src/inputstaff.cc
new file mode 100644
index 0000000000..2337f6ae2d
--- /dev/null
+++ b/src/inputstaff.cc
@@ -0,0 +1,79 @@
+#include "getcommand.hh"
+#include "debug.hh"
+#include "inputmusic.hh"
+#include "inputstaff.hh"
+#include "inputcommands.hh"
+#include "inputcommand.hh"
+#include "staffcommands.hh"
+#include "melodicstaff.hh"
+#include "rhythmstaff.hh"
+#include "staff.hh"
+
+void
+Input_staff::add(svec<Input_command*> &s)
+{
+    commands_.bottom().add(get_reset_command());
+    for (int i=0; i < s.sz(); i++)
+	commands_.bottom().add(s[i]);
+    s.set_size(0);
+}
+
+Input_staff::Input_staff(String s)
+{
+    type= s;
+}
+
+void
+Input_staff::add(Horizontal_music*m)
+{
+    music_.bottom().add(m);
+}
+
+Staff*
+Input_staff::parse(PointerList<Input_command*> score_wide)
+{
+    Staff *p=0;
+    
+    if (type == "melodic")
+	p = new Melodic_staff;
+    else if (type == "rhythmic")
+	p = new Rhythmic_staff;
+
+    for (PCursor<Horizontal_music*> i(music_); i.ok(); i++) {
+	Voice_list vl = i->convert();
+	p->add(vl);
+    }
+
+    Input_commands commands;
+    for (PCursor<Input_command*> i(score_wide); i.ok(); i++) 
+	commands.add(**i);
+    for (PCursor<Input_command*> i(commands_); i.ok(); i++) 
+	commands.add(**i);
+
+    p->staff_commands_ = commands.parse();
+
+    return p;
+}
+
+Input_staff::Input_staff(Input_staff&s)
+{
+    for (PCursor<Input_command*> i(s.commands_); i.ok(); i++)
+	commands_.bottom().add(new Input_command(**i));
+    for (PCursor<Horizontal_music*> i(s.music_); i.ok(); i++)
+	add(i);
+
+    type = s.type;
+}
+
+void
+Input_staff::print() const
+{
+#ifndef NPRINT
+    mtor << "Input_staff {\n";
+    for (PCursor<Input_command*> i(commands_); i.ok(); i++)
+	i->print();
+    for (PCursor<Horizontal_music*> i(music_); i.ok(); i++)
+	i->print();
+    mtor << "}\n";
+#endif
+}
diff --git a/src/key.cc b/src/key.cc
index 542549ddf9..55c79c0e1f 100644
--- a/src/key.cc
+++ b/src/key.cc
@@ -38,11 +38,11 @@ Local_key::reset(Key k)
 }
 
 svec<int>
-Key::read(svec<String> s)
+Key::read(svec<Scalar> s)
 {
     svec<int> newkey;
     for (int j = 0; j < 7; j++)
-     accidentals[j] = 0;
+	accidentals[j] = 0;
    
     for (int i=0; i < s.sz(); i++) {
 	int large, small;
@@ -56,7 +56,7 @@ Key::read(svec<String> s)
 }
 
 svec<int>
-Key::oldkey_undo(svec<String> s)
+Key::oldkey_undo(svec<Scalar>s)
 {
     svec<int> oldkey;
     svec<int> newkey;
diff --git a/src/lexer.l b/src/lexer.l
index ab97197fa9..aaacf06df5 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -44,18 +44,24 @@ REAL		[0-9]+(\.[0-9]*)?
 %%
 
 \$		{
-	BEGIN(notes); return '$';
+	BEGIN(notes); 
 }
 
 <notes>{NOTECOMMAND}	{
 	String c = YYText() +1;
+
 	int l = lookup_keyword(c);
-	if (l == -1) {
-		String e("unknown NOTECOMMAND: \\");
-		e += c;
-		yyerror(e);
+	if (l != -1)
+		return l;
+	Identifier * id = lookup_identifier(c);
+	if (id) {		
+		yylval.id = id;
+		return IDENTIFIER;
 	}
-	return l;
+	String *sp = new String( c);
+	mtor << "new id: " << *sp;
+	yylval.string=sp;
+	return NEWIDENTIFIER;
 }
 
 <notes>{RESTNAME} 	{
@@ -84,7 +90,7 @@ REAL		[0-9]+(\.[0-9]*)?
 
 }
 <notes>\$	{
-	BEGIN(INITIAL); return '$';
+	BEGIN(INITIAL); 
 }
 <notes>[{}]	{
 	return YYText()[0];
@@ -120,15 +126,16 @@ REAL		[0-9]+(\.[0-9]*)?
 		yyterminate();
 }
 {WORD}		{
-	int l = lookup_keyword(YYText());
+	String c = YYText();
+	int l = lookup_keyword(c);
 	if (l != -1)
 		return l;
-	Identifier * id = lookup_identifier(YYText());
+	Identifier * id = lookup_identifier(c);
 	if (id) {		
 		yylval.id = id;
 		return IDENTIFIER;
 	}
-	String *sp = new String( YYText());
+	String *sp = new String( c);
 	mtor << "new id: " << *sp;
 	yylval.string=sp;
 	return NEWIDENTIFIER;
diff --git a/src/linespace.cc b/src/linespace.cc
index 6b16c9afab..e8a767f9ee 100644
--- a/src/linespace.cc
+++ b/src/linespace.cc
@@ -226,6 +226,7 @@ Spacing_problem::print_ideal(const Idealspacing*id)const
     int r = col_id(id->right);
 
     mtor << "between " << l <<","<<r<<":" ;
+    id->print();
 #endif
 }
 
diff --git a/src/localkeyitem.cc b/src/localkeyitem.cc
index c8c67e76d8..a7de5ae695 100644
--- a/src/localkeyitem.cc
+++ b/src/localkeyitem.cc
@@ -1,5 +1,6 @@
 #include "localkeyitem.hh"
 #include "molecule.hh"
+#include "scalar.hh"
 #include "lookup.hh"
 #include "paper.hh"
 
diff --git a/src/lookup.cc b/src/lookup.cc
index 018c57f9c0..c22e3aaf55 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -3,6 +3,7 @@
 #include "symtable.hh"
 #include "dimen.hh"
 #include "tex.hh"
+#include "scalar.hh"
 
 Real
 Lookup::internote()
@@ -126,7 +127,7 @@ Lookup::linestaff(int lines, Real wid)
 
 
 Symbol
-Lookup::meter(svec<String> a)
+Lookup::meter(svec<Scalar> a)
 {
     Symbol s;
     s.dim.x = Interval( convert_dimen(0,"pt"),
diff --git a/src/melodicstaff.cc b/src/melodicstaff.cc
index a0c0b2e46f..b6d1ea59d7 100644
--- a/src/melodicstaff.cc
+++ b/src/melodicstaff.cc
@@ -66,17 +66,12 @@ Melodic_staff::get_rest(Rest_req*rq)
 {
     Rest*r = Simple_staff::get_rest(rq);
     if (rq->balltype <= 2)
-	r->translate(Offset(0, NO_LINES * paper()->internote()));
+	r->translate(Offset(0, (NO_LINES-1) * paper()->internote()));
     return r;
 }
 
-Melodic_staff*
-Melodic_staff::clone()const
-{
-    return new Melodic_staff(*this);
-}
-
-Local_key_item* Melodic_staff::get_local_key_item()
+Local_key_item*
+Melodic_staff::get_local_key_item()
 {
     return new Local_key_item(-2);
 }
diff --git a/src/meter.cc b/src/meter.cc
index 29375b8aba..14b242e5c6 100644
--- a/src/meter.cc
+++ b/src/meter.cc
@@ -1,11 +1,10 @@
-#include "string.hh"
+#include "scalar.hh"
 #include "molecule.hh"
 #include "meter.hh"
 #include "paper.hh"
 #include "lookup.hh"
 
-
-Meter::Meter(svec<String> a)
+Meter::Meter(svec<Scalar>a)
     :args(a)
 {
 }
diff --git a/src/parser.y b/src/parser.y
index abacc7add9..23c779ed7d 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -3,16 +3,17 @@
 
 #include "lexer.hh"
 #include "paper.hh"
-#include "staff.hh"
-#include "score.hh"
+#include "inputstaff.hh"
+#include "inputscore.hh"
+#include "inputmusic.hh"
 #include "main.hh"
 #include "keyword.hh"
-#include "getcommand.hh"
+#include "inputcommand.hh"
 #include "debug.hh"
 #include "parseconstruct.hh"
 #include "dimen.hh"
 #include "identifier.hh"
-#include "inputmusic.hh"
+
 
 #ifndef NDEBUG
 #define YYDEBUG 1
@@ -24,13 +25,11 @@ svec<Request*> pre_reqs, post_reqs;
 
 %union {    
     Real real;
-    Command *command;
+    Input_command *command;
     Identifier *id;    
     Voice *voice;    
     Voice_element *el;	
-    Staff *staff;    
     String *string;
-    Score *score;
     const char *consstr;
     Paperdef *paper;
     Request* request;
@@ -42,15 +41,17 @@ svec<Request*> pre_reqs, post_reqs;
     char c;
 
     svec<String> * strvec;
-    svec<Command*> *commandvec;
+    svec<Input_command*> *commandvec;
     Voice_list *voicelist;
+	Input_staff *staff;    
+	Input_score *score;
 }
 
-%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
+%token VOICE STAFF SCORE TITLE  BAR NOTENAME OUTPUT
 %token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
-%token MELODICSTAFF GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
+%token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
 %token KEY CLEF VIOLIN BASS MULTI TABLE CHORD VOICES
-%token PARTIAL
+%token PARTIAL RHYTHMIC MELODIC MUSIC
 
 %token <id>  IDENTIFIER
 %token <string> NEWIDENTIFIER 
@@ -69,8 +70,7 @@ svec<Request*> pre_reqs, post_reqs;
 %type <el> voice_elt full_element
 %type <command> score_command staff_command skipcommand
 %type <score> score_block score_body
-%type <staff> staff_block  rhythmstaff_block rhythmstaff_body
-%type <staff> melodicstaff_block melodicstaff_body staffdecl
+%type <staff> staff_block staff_init staff_body
 %type <i> int
 %type <commandvec> score_commands_block score_commands_body
 %type <commandvec> staff_commands_block staff_commands_body
@@ -81,7 +81,7 @@ svec<Request*> pre_reqs, post_reqs;
 %type <chord> music_chord music_chord_body
 %type <horizontal>  horizontal_music
 %type <mvoice>  music_voice_body music_voice
-%type <voicelist> voices
+
 
 %%
 
@@ -89,7 +89,7 @@ mudela:	/* empty */
 	| mudela score_block { 
 		add_score($2);
 	}
-	| mudela add_declaration {	}
+	| mudela add_declaration { }
 	;
 /*
 	DECLARATIONS
@@ -104,8 +104,12 @@ declaration:
 		$$ = new Staff_id(*$1, $3);
 		delete $1; // this sux
 	}
-	| NEWIDENTIFIER '=' voices {
-		$$ = new Voices_id(*$1, $3);
+	| NEWIDENTIFIER '=' music_voice {
+		$$ = new M_voice_id(*$1, $3);
+		delete $1;
+	}
+	| NEWIDENTIFIER '=' music_chord  {
+		$$ = new M_chord_id(*$1, $3);
 		delete $1;
 	}
 	;
@@ -117,7 +121,7 @@ declaration:
 score_block: SCORE '{' score_body '}' 	{ $$ = $3; }
 	;
 
-score_body:		{ $$ = new Score; } 
+score_body:		{ $$ = new Input_score; }
 	| score_body staff_block	{ $$->add($2); }
 	| score_body score_commands_block 	{
 		$$->add(*$2);
@@ -132,7 +136,7 @@ score_commands_block:
 	COMMANDS '{' score_commands_body '}' { $$ =$3;}
 	;
 
-score_commands_body:			{ $$ = new svec<Command*>; }
+score_commands_body:			{ $$ = new svec<Input_command*>; }
 	| score_commands_body score_command		{
 		$$->add($2);
 	}
@@ -143,7 +147,7 @@ staff_commands_block: COMMANDS '{' staff_commands_body '}'	{
 	;
 
 staff_commands_body:
-	/* empty */			{ $$ = new svec<Command*>; }
+	/* empty */			{ $$ = new svec<Input_command*>; }
 	| staff_commands_body staff_command	{
 		$$->add($2);
 	}
@@ -151,9 +155,9 @@ staff_commands_body:
 
 staff_command:
 	skipcommand
-	| KEY '$' pitch_list '$'	{/*UGH*/
-		$$ = get_key_interpret_command(*$3);
-		delete $3;
+	| KEY  pitch_list 	{/*UGH*/
+		$$ = get_key_interpret_command(*$2);
+		delete $2;
 	}
 	| CLEF clef_id			{
 		$$ = get_clef_interpret_command(*$2);
@@ -197,56 +201,35 @@ paper_body:
 	STAFFs
 */
 staff_block:
-	staffdecl
-	| rhythmstaff_block
-	| melodicstaff_block
+	 STAFF '{' staff_body '}' 	{ $$ = $3; }
 	;
 
-staffdecl: STAFF '{' IDENTIFIER '}' { $$ = $3->staff()->clone(); }
-	;
 
-rhythmstaff_block:
-	RHYTHMSTAFF '{' rhythmstaff_body '}'	{ $$ = $3; }
-	;
 
-rhythmstaff_body:
-	/* empty */			{ $$ = get_new_rhythmstaff(); }
-	| rhythmstaff_body voices	{ $$->add(*$2);
-		delete $2;
+staff_init:
+	IDENTIFIER		{ $$ = new Input_staff(*$1->staff()); }
+	| RHYTHMIC		{
+		$$ = new Input_staff("rhythmic");
 	}
-	| rhythmstaff_body staff_commands_block {
-		$$->add(*$2);
-		delete $2;
+	| MELODIC		{
+		$$ = new Input_staff( "melodic");
 	}
 	;
 
-melodicstaff_block:
-	MELODICSTAFF '{' melodicstaff_body '}'	{ $$ = $3; }
-	;
-
-melodicstaff_body:
-	/* empty */			{ $$ = get_new_melodicstaff(); }
-	| melodicstaff_body voices	{
-		$$->add(*$2);
-		delete $2;
-	}	
-	| melodicstaff_body staff_commands_block {
-		$$->input_commands_.add(get_reset_command());
+staff_body:
+	staff_init
+	| staff_body		horizontal_music	{
+		$$->add($2);
+	}
+	| staff_body staff_commands_block {
 		$$->add(*$2);
 		delete $2;
-	} 	
-	;
-
-voices:
-	'$' music_voice_body '$'  {
-		$$ = new Voice_list($2->convert());
-	}
-	| VOICES '{' IDENTIFIER '}' 	{
-		$$ = new Voice_list(*$3->voices());
 	}
 	;
 
-
+/*
+	MUSIC
+*/
 horizontal_music:
 	music_voice	{ $$ = $1; }
 	;
@@ -255,12 +238,15 @@ vertical_music:
 	music_chord	{ $$ = $1; }
 	;
 
-music_voice: VOICE '{' music_voice_body '}'	{ $$ = $3; }
+music_voice: MUSIC '{' music_voice_body '}'	{ $$ = $3; }
 	;
 
 music_voice_body:			{
 		$$ = new Music_voice;
 	}
+	| music_voice_body IDENTIFIER {
+		$$->concatenate($2->mvoice());
+	}
 	| music_voice_body full_element {
 		$$->add($2);
 	}
@@ -278,6 +264,9 @@ music_chord: CHORD '{' music_chord_body '}'	{ $$ = $3; }
 music_chord_body:		{
 		$$ = new Music_general_chord;
 	}
+	| music_voice_body IDENTIFIER {
+		$$->concatenate($2->mchord());
+	}
 	| music_chord_body horizontal_music {
 		$$ -> add($2);
 	}
diff --git a/src/pcol.cc b/src/pcol.cc
index 41cf4fdb67..2fab154829 100644
--- a/src/pcol.cc
+++ b/src/pcol.cc
@@ -3,33 +3,6 @@
 #include "pstaff.hh"
 #include "debug.hh"
 
-void
-Idealspacing::print() const
-{
-#ifndef NPRINT
-    mtor << "idealspacing {" ;
-    mtor << "distance "<<space<< " strength " << hooke << "}\n";
-#endif
-}
-
-Idealspacing::Idealspacing(const PCol * l,const PCol * r)
-{
-    space = 0.0;
-    hooke = 0.0;
-    left = l;
-    right = r;
-}
-
-void
-Idealspacing::OK() const
-{
-#ifndef NDEBUG
-    assert(hooke >= 0 && left  && right);
-#endif    
-}
-
-/****************************************************************/
-
 Interval
 PCol::width() const
 {
@@ -41,19 +14,27 @@ PCol::width() const
 	w.unite(Interval(0,0));
     return w;
 }
+int
+PCol::rank() const
+{
+    if(!pscore_)
+	return -1;
+    PCursor<PCol*> me=pscore_->find_col(this);
+    if (!me.ok())
+	return -1;
+    PCursor<PCol*> bot(pscore_->cols.top());
+    return me - bot;
+}
 
 void
 PCol::print() const
 {
 #ifndef NPRINT
     mtor << "PCol {";
-    if (pscore_) {		// ugh
-	PCursor<PCol*> me=pscore_->find_col(this);
-	PCursor<PCol*> bot(pscore_->cols.top());
-	if (me.ok()) {
-	    mtor << "rank: " << me - bot << '\n';
-	}
-    }
+
+    if (rank() >= 0)
+	mtor << "rank: " << rank() << '\n';
+
     mtor << "# symbols: " << its.size() ;
     if (breakable()){
 	mtor << "\npre,post: ";
diff --git a/src/pscore.cc b/src/pscore.cc
index c12f6ddce6..378ad37f0a 100644
--- a/src/pscore.cc
+++ b/src/pscore.cc
@@ -199,11 +199,6 @@ PScore::print() const
 void
 PScore::preprocess()
 {
-#if 0
-    for (PCursor<Item*> ic(its); ic.ok(); ic++){
-	ic->preprocess();
-    }
-#endif 
 }
 
 void
@@ -222,11 +217,11 @@ PScore::postprocess()
 PCursor<PCol *>
 PScore::find_col(const PCol *c)const
 {
-    PCursor<PCol*> cc(cols);
-    for (; cc.ok(); cc++)
-	if (cc.ptr() == c || cc->prebreak == c || cc->postbreak == c)
-	    return cc;
-    return cc;
+    PCol*what = (PCol*)c;
+    if (what->daddy )
+	what = what -> daddy;
+    
+    return cols.find(what);
 }
 
 void
diff --git a/src/rhythmstaff.cc b/src/rhythmstaff.cc
index 6c986a62cc..d5f26dcd43 100644
--- a/src/rhythmstaff.cc
+++ b/src/rhythmstaff.cc
@@ -59,10 +59,3 @@ get_new_rhythmstaff()
     return new Rhythmic_staff;
 }
 
-
-
-Rhythmic_staff*
-Rhythmic_staff::clone() const
-{
-    return new Rhythmic_staff(*this);
-}
diff --git a/src/sccol.cc b/src/sccol.cc
index c29d26cf4a..be242059af 100644
--- a/src/sccol.cc
+++ b/src/sccol.cc
@@ -26,3 +26,24 @@ Score_column::print() const
     mtor << "}\n";
 #endif
 }
+
+int
+Real_compare(Real &a , Real& b)
+{
+    return sgn(a-b);
+}
+
+void
+Score_column::preprocess()
+{
+    durations.sort(Real_compare);
+}
+void
+Score_column::add_duration(Real d)
+{
+    for (int i = 0; i< durations.sz(); i++) {
+	if (d == durations[i])
+	    return ;
+    }
+    durations.add(d);
+}
diff --git a/src/score.cc b/src/score.cc
index 60ab3931f9..57336936b5 100644
--- a/src/score.cc
+++ b/src/score.cc
@@ -1,7 +1,4 @@
-#include "staffcommands.hh"
 #include "tstream.hh"
-#include "getcommand.hh"
-#include "inputcommands.hh"
 #include "score.hh"
 #include "sccol.hh"
 #include "pscore.hh"
@@ -9,6 +6,7 @@
 #include "debug.hh"
 #include "paper.hh"
 
+
 void
 Score::process()
 {
@@ -18,20 +16,21 @@ Score::process()
 	paper_ = new Paperdef;
     
     /// distribute commands to disciples
-    distribute_commands();
-    
     pscore_ = new PScore(paper_);
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-	sc->set_output(pscore_);
-	sc->process();
+    for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+	i->process_commands(last());
+	i->set_output(pscore_);
+	i->process();
     }
 
     // do this after processing, staffs first have to generate PCols.
     do_pcols();
+    // ugh. Would want to clean the columns before anything else.
+    clean_cols();
     calc_idealspacing();
-    clean_cols();		// ugh. Would want to clean the columns before anything else.
-
 
+    // debugging
+    print ();
     OK();
 
     pscore_->preprocess();
@@ -49,16 +48,16 @@ Score::process()
 void
 Score::clean_cols()
 {    
-    for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
-	sc->clean_cols();
+    for (PCursor<Staff * > i(staffs_); i.ok(); i++)
+	i->clean_cols();
     
     for (PCursor<Score_column*> c(cols_); c.ok(); ) {
 	if (!c->pcol_->used()) {
-	    mtor << "removing : ";
-	    c->print();
 	    c.del();
-	} else
+	} else {
+	    c->preprocess();
 	    c++;
+	}
     }
     
     pscore_->clean_cols();
@@ -114,27 +113,12 @@ Score::find_col(Real w,bool mus)
     return scc;
 }
 
-void
-Score::distribute_commands()
-{
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-	sc->process_input_commands(input_commands_, last());
-    }
-}
-void
-Score::add(Staff*s)
-{
-    s->score_ = this;
-    staffs_.bottom().add(s);    
-}
-
-
 void
 Score::do_pcols()
 {
-    PCursor<Score_column*> sc(cols_);
-    for (; sc.ok(); sc++) {
-	pscore_->add(sc->pcol_);
+    PCursor<Score_column*> i(cols_);
+    for (; i.ok(); i++) {
+	pscore_->add(i->pcol_);
     }
 }
 Real
@@ -151,9 +135,9 @@ void
 Score::OK() const
 {
 #ifndef NDEBUG
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-	sc->OK();
-	assert(sc->score_ == this);
+    for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+	i->OK();
+	assert(i->score_ == this);
     }
     staffs_.OK();
     cols_.OK();
@@ -169,34 +153,28 @@ Score::print() const
 {
 #ifndef NPRINT
     mtor << "score {\n"; 
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-	sc->print();
+    for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+	i->print();
     }
-    for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
-	sc->print();
+    for (PCursor<Score_column*> i(cols_); i.ok(); i++) {
+	i->print();
     }
+    if (pscore_)
+	pscore_->print();
+    
     mtor << "}\n";
 #endif
 }
 
-Score::Score()
+Score::Score(Paperdef*p)
 {
     pscore_=0;
-    paper_ = 0;
+    paper_ = p;
 }
 
 Score::~Score()
 {
     delete pscore_;
-    for (int i=0; i<input_commands_.sz(); i++)
-	delete input_commands_[i];    
-    delete paper_;
-}
-void
-Score::set(Paperdef*p)
-{
-    delete paper_;
-    paper_ = p;
 }
 
 void
@@ -212,10 +190,11 @@ Score::output(String s)
 }
 
 
+
 void
-Score::add(svec<Command*> &s)
+Score::add(Staff*s)
 {
-    input_commands_.add(get_reset_command());
-    input_commands_.concat(s);
+    s->score_ = this;
+    staffs_.bottom().add(s);
 }
 
diff --git a/src/scores.cc b/src/scores.cc
index 04efd6e4b1..b7b854881b 100644
--- a/src/scores.cc
+++ b/src/scores.cc
@@ -1,26 +1,29 @@
 #include "main.hh"
+#include "inputscore.hh"
 #include "score.hh"
 #include "string.hh"
 
-static svec<Score*> sv;
+static svec<Input_score*> sv;
 
 static String outfn="lelie.uit";
 
 // todo: check we don't overwrite default output.
-
 void
 do_scores()
 {
-    for (int i=0; i < sv.sz(); i++) {	
-	sv[i]->process();
-	sv[i]->output(outfn);
+    for (int i=0; i < sv.sz(); i++) {
+	Score * s = sv[i]->parse();	
 	delete sv[i];
-	sv[i] =0;
+
+	s->process();
+	s->output(outfn);
+	delete s;
+
     }
 }
 
 void
-add_score(Score * s)
+add_score(Input_score * s)
 {
     sv.add(s);
 }
diff --git a/src/simpleprint.cc b/src/simpleprint.cc
index 3a0ac3dde3..833afe2108 100644
--- a/src/simpleprint.cc
+++ b/src/simpleprint.cc
@@ -13,7 +13,7 @@ Item *
 Simple_staff::get_TYPESET_item(Command *com)
 {
     Item *s=0;
-    svec<String> arg( com->args);
+    svec<Scalar> arg( com->args);
     String type =arg[0];
     arg.del(0);
     if (type ==  "BAR" ) {
diff --git a/src/simplewalker.cc b/src/simplewalker.cc
index 7705e045a9..8d056e59ce 100644
--- a/src/simplewalker.cc
+++ b/src/simplewalker.cc
@@ -22,7 +22,7 @@ Simple_walker::do_INTERPRET_command(Command*com)
     if (com->args[0] == "BAR") {
 	local_key_.reset(key_);
     } else if (com->args[0] == "KEY") {
-	svec<String> s(com->args);
+	svec<Scalar>s(com->args);
 	s.del(0);
 	if (com->when) {
 	    assert(!oldkey_undo);
@@ -32,7 +32,7 @@ Simple_walker::do_INTERPRET_command(Command*com)
 	typesetkey = key_.read(s);
 	local_key_.reset(key_);	
     } else if (com->args[0] == "CLEF") {
-	svec<String> s(com->args);
+	svec<Scalar>s(com->args);
 	s.del(0);
 	clef_.read(s);
     } else {
diff --git a/src/slur.cc b/src/slur.cc
index 171f3b04dd..8b46ec771b 100644
--- a/src/slur.cc
+++ b/src/slur.cc
@@ -1,4 +1,5 @@
 #include "slur.hh"
+#include "scalar.hh"
 #include "lookup.hh"
 #include "paper.hh"
 #include "notehead.hh"
diff --git a/src/staff.cc b/src/staff.cc
index 9b65539de5..521d31635d 100644
--- a/src/staff.cc
+++ b/src/staff.cc
@@ -2,51 +2,23 @@
 #include "score.hh"
 #include "voice.hh"
 #include "swalker.hh"
-#include "getcommand.hh"
 #include "stcol.hh"
 #include "sccol.hh"
-#include "inputcommands.hh"
 #include "staffcommands.hh"
 #include "debug.hh"
 
-Staff::Staff(Staff const&src)
-{
-    PL_copy(voices,src.voices);
-    staff_commands_ = src.staff_commands_;
-    assert(!cols.size());	// cols is a runtime field.
-    input_commands_ = src.input_commands_;
-    
-    score_ = src.score_;
-    pscore_ = src.pscore_;
-}
-
-void
-Staff::add(svec<Command*> &s)
-{
-    input_commands_.add(get_reset_command());
-    input_commands_.concat(s);
-}
 void
 Staff::add(PointerList<Voice*> &l)
 {
     for (PCursor<Voice*> i(l); i.ok(); i++)
 	voices.bottom().add(i);
 }
+
 void
-Staff::process_input_commands(svec<Command*> &s, Real l)
+Staff::process_commands(Real l)
 {
-    Input_commands commands;
-    for (int i = 0 ; i< s.sz(); i++)
-	commands.add(new Command(*s[i]));
-    for (int i = 0 ; i< input_commands_.sz(); i++)
-	commands.add(input_commands_[i]);
-    commands.truncate(l);
-    commands.print();
-    
-    staff_commands_ = commands.parse();
-    staff_commands_->clean(l);
-    commands.print();    
-    print();
+    if (staff_commands_)
+	staff_commands_->clean(l);
 }
 
 Paperdef*
@@ -80,6 +52,7 @@ Staff::get_col(Real w, bool mus)
 	if (sc == i->score_column)
 	    return i;
     }
+
     /* post: *sc > *->score_column || !i.ok() */
     Staff_column* newst = create_col(sc);
 
@@ -108,11 +81,6 @@ Staff::get_col(Real w, bool mus)
 }
 
 
-void
-Staff::add_voice(Voice *v)
-{
-    voices.bottom().add(v);
-}
 
 /*
     put all stuff grouped vertically in the Staff_cols
@@ -120,9 +88,9 @@ Staff::add_voice(Voice *v)
 void
 Staff::setup_staffcols()
 {    
-    for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
-	Real now = vc->start;
-	for (PCursor<Voice_element *> ve(vc->elts); ve.ok(); ve++) {
+    for (PCursor<Voice*> i(voices); i.ok(); i++) {
+	Real now = i->start;
+	for (PCursor<Voice_element *> ve(i->elts); ve.ok(); ve++) {
 
 	    Staff_column *sc=get_col(now,true);
 	    sc->add(ve);
@@ -159,8 +127,8 @@ Real
 Staff::last() const
 {
     Real l = 0.0;
-    for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
-	l = MAX(l, vc->last());
+    for (PCursor<Voice*> i(voices); i.ok(); i++) {
+	l = MAX(l, i->last());
     }
     return l;
 }
@@ -171,13 +139,11 @@ Staff::print() const
 {
 #ifndef NPRINT
     mtor << "Staff {\n";
-    for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
-	vc->print();	
+    for (PCursor<Voice*> i(voices); i.ok(); i++) {
+	i->print();	
     }
     if (staff_commands_)
 	staff_commands_->print();
-    for (int i =0; i <input_commands_.sz(); i++)
-	input_commands_[i]->print();
     mtor <<"}\n";
 #endif
 }
diff --git a/src/stcol.cc b/src/stcol.cc
index 799daed316..abb27d17da 100644
--- a/src/stcol.cc
+++ b/src/stcol.cc
@@ -19,7 +19,7 @@ Staff_column::add(Voice_element*ve)
 {
     Real d= ve->duration;
     if (d){
-	score_column->durations.add(d);
+	score_column->add_duration(d);
     }
 	
     v_elts.add(ve);
@@ -28,3 +28,4 @@ Staff_column::add(Voice_element*ve)
 Staff_column::Staff_column(Score_column*s) {
     score_column = s;
 }
+
diff --git a/src/stem.cc b/src/stem.cc
index 8ba21e82c6..5fa4d9ee30 100644
--- a/src/stem.cc
+++ b/src/stem.cc
@@ -98,7 +98,8 @@ Stem::set_default_extents()
     set_stemend((dir< 0) ? maxnote-stemlen: minnote +stemlen);
     if (dir > 0){	
 	stem_xoffset = paper()->note_width();
-    }
+    } else
+	stem_xoffset = 0;
 }
 
 void
@@ -160,5 +161,5 @@ Stem::hpos()const
 void
 Stem::preprocess()
 {
- 
+    set_default_extents();	// needed for the flags.
 }
diff --git a/src/table.cc b/src/table.cc
index 7a54241f9f..cfb0db0cb9 100644
--- a/src/table.cc
+++ b/src/table.cc
@@ -1,7 +1,8 @@
 #include "glob.hh"
 #include "debug.hh"
 #include "string.hh"
-#include "identifier.hh"
+#include "inputstaff.hh"
+#include "identparent.hh"
 #include "keyword.hh"
 #include "associter.hh"
 #include "parser.hh"
@@ -16,7 +17,7 @@ static Keyword_ent the_key_tab[]={
     "geometric", GEOMETRIC,
     "in", IN,
     "key", KEY, 
-    "melodicstaff", MELODICSTAFF,
+    "melodic", MELODIC,
     "meter", METER,
     "mm", MM,
     "octave", OCTAVECOMMAND,
@@ -24,7 +25,7 @@ static Keyword_ent the_key_tab[]={
     "partial", PARTIAL,
     "paper", PAPER,
     "pt", PT,
-    "rhythmstaff", RHYTHMSTAFF,
+    "rhythmic", RHYTHMIC,
     "score", SCORE,
     "skip", SKIP,
     "staff", STAFF,
@@ -36,9 +37,10 @@ static Keyword_ent the_key_tab[]={
     "violin", VIOLIN,
     "voice", VOICE,
     "voices", VOICES,
-    "width", WIDTH,   
+    "width", WIDTH,
+    "music", MUSIC,
     0,0
-} ;
+};
 
 
 int
diff --git a/src/template3.cc b/src/template3.cc
index 80921422fa..d9c85526d7 100644
--- a/src/template3.cc
+++ b/src/template3.cc
@@ -1,4 +1,8 @@
 #include "command.hh"
+#include "inputscore.hh"
+#include "inputstaff.hh"
+#include "inputmusic.hh"
+#include "inputcommand.hh"
 #include "molecule.hh"
 #include "plist.cc"
 
diff --git a/src/tex.cc b/src/tex.cc
index 60d487dfd1..372536c20a 100644
--- a/src/tex.cc
+++ b/src/tex.cc
@@ -31,3 +31,12 @@ substitute_args(String source, svec<String> args)
         substitute_arg(retval, "");
     return retval;
 }
+String
+substitute_args(String source, svec<Scalar> args)    
+{
+    svec<String> sv;
+    for (int i = 0 ; i < args.sz(); i++)
+	sv.add(args[i]);
+    
+    return substitute_args(source, sv);
+}
diff --git a/src/texbeam.cc b/src/texbeam.cc
index 01545405c6..87967119b1 100644
--- a/src/texbeam.cc
+++ b/src/texbeam.cc
@@ -4,12 +4,13 @@
   
   */
 
-  #include <math.h>
+#include <math.h>
 #include "symbol.hh"
 #include "molecule.hh"
 #include "tex.hh"
 #include "symtable.hh"
 #include "dimen.hh"
+#include "debug.hh"
 #include "lookup.hh"
 
 Symbol
@@ -32,7 +33,11 @@ Lookup::beam_element(int sidx, int widx, Real slope)
 static int
 slope_index(Real &s)
 {
-    assert(ABS(s) < 0.45);
+    if (ABS(s) > 0.5) {
+	WARN << "beam steeper than 0.5";
+	s = sgn(s) * 0.5;
+    }
+
     int i = int(rint(s *  20.0));
 
     s = i/20.0;
diff --git a/src/texslur.cc b/src/texslur.cc
index e3966daaa6..799b9e7e6d 100644
--- a/src/texslur.cc
+++ b/src/texslur.cc
@@ -1,6 +1,7 @@
+#include <math.h>
+
 #include "lookup.hh"
 #include "molecule.hh"
-#include <math.h>
 #include "dimen.hh"
 #include "debug.hh"
 
@@ -31,7 +32,10 @@ Lookup::half_slur_middlepart(Real &dx, int dir)
 	error ("halfslur too large");
     int    widx = int(floor(dx / 4.0));
     dx = widx * 4.0;
-    widx --;	
+    if (widx) widx --;
+    else {
+	WARN <<  "slur too narrow\n";
+    }
 
     Symbol s;
     
@@ -62,13 +66,19 @@ Lookup::half_slur(int dy, Real &dx, int dir, int xpart)
 
     int widx;
     	 	
-    if (dx >= convert_dimen(96,"pt"))
+    if (dx >= convert_dimen(96,"pt")) {
+	WARN << "Slur half too wide.";
 	dx =  convert_dimen(96,"pt");
+    }
     
     widx = int(rint(dx/12.0));
     dx = widx*12.0;
-    widx --;
-
+    if (widx)
+	widx --;
+    else {
+	WARN <<  "slur too narrow\n";
+    }
+	
     Symbol s;
     s.dim.x = Interval(0,dx);
     s.dim.y = Interval(MIN(0,dy), MAX(0,dy));
@@ -116,7 +126,12 @@ Lookup::slur (int dy , Real &dx, int dir)
     
     int widx = int(floor(dx/4.0)); // slurs better too small..
     dx = 4.0 * widx;
-    widx--;
+    if (widx)
+	widx --;
+    else {
+	WARN <<  "slur too narrow\n";
+    }
+
     int hidx = dy;
     if (hidx <0)
 	hidx = -hidx;
-- 
2.39.5