From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Wed, 11 Dec 1996 23:26:56 +0000 (+0100)
Subject: release: 0.0.13
X-Git-Tag: release/0.0.13
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=517134c0b706918d7a07b7f8a6e0e39232042e82;p=lilypond.git

release: 0.0.13
---

diff --git a/.dstreamrc b/.dstreamrc
index bb7e1bb71d..2eb8e1df67 100644
--- a/.dstreamrc
+++ b/.dstreamrc
@@ -20,3 +20,8 @@ Note_req		1
 Rhythmic_req		1
 Rest_req		1
 delete_identifiers	1
+Staff			0
+Voice			0
+Voice_element		0
+Request			1
+Input_cursor		1
\ No newline at end of file
diff --git a/README b/README
index d60b5b8ca4..757ed1d173 100644
--- a/README
+++ b/README
@@ -13,8 +13,10 @@ LilyPond is updated very frequently, the latest version is always available at:
 
 PREREQUISITES
 
-TeX, the MusixTeX fonts, g++ > v2.7. The "flower" library, which should be
-available from the same source you got this from.
+TeX, the MusixTeX fonts, g++ > v2.7. The "flower" library, which
+should be available from the same source you got this from. The
+Makefile uses perl for trivial operation, but you could tinker with it
+to use sed or awk.
 
 COMPILING
 
@@ -70,7 +72,7 @@ stacktrace of the crash.
 HOW DOES IT WORK
 
 * Use The Source, Luke. If you don't know C++, you can try editing
-.dstreamrc for copious debugging output.
+.dstreamrc for copious debugging output. (use -d)
 
 * the subdir Documentation/ contains some in depth matter on LilyPond
 algorithms
diff --git a/Sources.make b/Sources.make
index c4d585bc6a..1dcc72a3c7 100644
--- a/Sources.make
+++ b/Sources.make
@@ -9,12 +9,13 @@ hdr=    qlp.hh linespace.hh qlpsolve.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 scommands.hh melodicstaff.hh\
+	sccol.hh stcol.hh staffcommands.hh melodicstaff.hh\
 	identifier.hh simplestaff.hh spanner.hh stem.hh\
 	notehead.hh leastsquares.hh beam.hh rest.hh\
 	swalker.hh bar.hh meter.hh accidental.hh\
 	key.hh keyitem.hh localkeyitem.hh simplewalker.hh\
-	clef.hh clefitem.hh slur.hh
+	clef.hh clefitem.hh slur.hh inputcommands.hh\
+	getcommand.hh inputmusic.hh
 
 mycc=   qlp.cc qlpsolve.cc \
 	break.cc linespace.cc molecule.cc staffline.cc\
@@ -25,7 +26,7 @@ mycc=   qlp.cc qlpsolve.cc \
 	warn.cc debug.cc symtable.cc boxes.cc\
 	pstaff.cc  tstream.cc\
 	calcideal.cc scores.cc identifier.cc \
-	dimen.cc paper.cc lookup.cc scommands.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\
@@ -33,5 +34,10 @@ mycc=   qlp.cc qlpsolve.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\
 	template1.cc template2.cc template3.cc template4.cc\
 	version.cc
+
+
+
diff --git a/Variables.make b/Variables.make
index f8cd146ba4..87c92fc64d 100644
--- a/Variables.make
+++ b/Variables.make
@@ -18,7 +18,7 @@ EXTRACXXFLAGS=-pipe -Wall -W  -pedantic
 # version info
 MAJVER=0
 MINVER=0
-PATCHLEVEL=11
+PATCHLEVEL=13
 VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
 
 # directories
@@ -53,7 +53,7 @@ DNAME=$(PACKAGENAME)-$(VERSION)
 # distribution files.
 othersrc=lexer.l parser.y
 SCRIPTS=make_version make_patch genheader
-IFILES=dimen.tex symbol.ini kortjakje.ly maartje.ly\
+IFILES=dimen.tex symbol.ini kortjakje.ly pavane.ly  maartje.ly\
 	lilyponddefs.tex test.tex .dstreamrc
 OFILES=Makefile Variables.make Sources.make COPYING README
 DFILES=$(OFILES) $(IFILES) $(SCRIPTS)
diff --git a/dimen.tex b/dimen.tex
index f0198c6c75..f1c9bad686 100644
--- a/dimen.tex
+++ b/dimen.tex
@@ -1,7 +1,9 @@
 \font\musicfnt=musix20
-%\def\mb#1{{\musicfnt\musicfnt\char#1}}
-\font\slurfont=xslhz20
-\def\mb#1{{\musicfnt\slurfont\char#1}}
+\font\slurfont=xslhu20
+\def\thefont{\musicfnt}
+
+\def\mb#1{{\thefont\char#1}}
+
 \newdimen\wid
 \newdimen\inc
 \newdimen\here
diff --git a/flower/Makefile b/flower/Makefile
index 25e9384d56..56e0da5e16 100644
--- a/flower/Makefile
+++ b/flower/Makefile
@@ -1,6 +1,6 @@
 MAJVER=1
 MINVER=0
-PATCHLEVEL=12
+PATCHLEVEL=13
 
 PACKAGENAME=flower
 VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
diff --git a/flower/Sources.make b/flower/Sources.make
index 044543beee..c7efa127f9 100644
--- a/flower/Sources.make
+++ b/flower/Sources.make
@@ -10,5 +10,5 @@ hh=cursor.hh pcursor.hh lgetopt.hh link.hh list.hh dstream.hh \
 	findcurs.hh unionfind.hh compare.hh handle.hh matrix.hh\
 	smat.hh vsmat.hh  vector.hh  real.hh choleski.hh\
 	tsmat.hh tvsmat.hh plist.hh associter.hh fproto.hh\
-	interval.hh scalar.hh
+	interval.hh scalar.hh sstack.hh
 
diff --git a/flower/associter.hh b/flower/associter.hh
index 6103f2266c..0902c3953d 100644
--- a/flower/associter.hh
+++ b/flower/associter.hh
@@ -14,9 +14,9 @@ template<class K, class V>
 struct Assoc_iter {
     int i;
     Assoc<K,V> &assoc_;
-    
-    Assoc_iter(Assoc<K,V> &a) :
-	assoc_(a)
+    /// we don't want to be bothered by const correctness
+    Assoc_iter(const Assoc<K,V> &a) :
+	assoc_((Assoc<K,V> &)a)
     {	
 	i= next(0);
     }
diff --git a/flower/compare.hh b/flower/compare.hh
index 9f9d4e5906..df278a2bfb 100644
--- a/flower/compare.hh
+++ b/flower/compare.hh
@@ -6,18 +6,36 @@
 #ifndef COMPARE_HH
 #define COMPARE_HH
 
+#define one_operator(type, function, op) \
+inline bool \
+operator op (type t1, type t2) {\
+    return function(t1, t2) op 0;\
+}\
 
-#define one_operator(type, function, op)        \
-inline bool operator op (type t1, type t2) { return function(t1, t2) op 0; }	
+#define gpp_minmax_operator(type, op, opp) \
+inline type \
+operator op(type t1, type t2)\
+{\
+     return (t1 opp t2) ? t1 :  t2;\
+}\
+
+#ifdef __GNUC__
+#define gpp_minmax(type, prefix)\
+       prefix gpp_minmax_operator(type, <?, <)\
+       prefix gpp_minmax_operator(type, >?, >)
+#else
+#define gpp_minmax(type, prefix)
+#endif
 
 /// handy notations for a signed comparison
-#define template_instantiate_compare(type, function, prefix)				\
+#define template_instantiate_compare(type, function, prefix) \
 prefix one_operator(type, function, >)\
 prefix one_operator(type, function, >=)\
 prefix one_operator(type, function, ==)\
 prefix one_operator(type, function, !=)\
 prefix one_operator(type, function, <)\
 prefix one_operator(type, function, <=)\
+gpp_minmax(type, prefix)\
 prefix inline type MAX(type t1, type t2) {  return (t1 > t2 )? t1 : t2; }\
 prefix inline type MIN(type t1, type t2) {  return (t1 < t2 )? t1 : t2; }\
   \
diff --git a/flower/plist.hh b/flower/plist.hh
index 704a883f83..19db901f8a 100644
--- a/flower/plist.hh
+++ b/flower/plist.hh
@@ -20,9 +20,12 @@ class PointerList : public List<void *>
     void concatenate(PointerList<T> const &s) { List<void*>::concatenate(s); }
     PointerList() {}
 };
+/** This class does no deletion of the pointers, but it knows how to
+  copy itself (shallow copy). We could have derived it from List<T>,
+  but this design saves a lot of code dup; for all PointerLists in the
+  program only one parent List<void*> is instantiated.  */
 
-
-/// intrusive pl. deletes pointers given to it.
+///  pl. which deletes pointers given to it.
 template<class T>
 struct IPointerList : public PointerList<T> {
     IPointerList(IPointerList&) { set_empty(); }
@@ -33,6 +36,7 @@ protected:
 };
 /**
   NOTE:
+  
   The copy constructor doesn't do what you'd want:
   Since T might have a virtual ctor, we don't try to do a
 
diff --git a/flower/sstack.hh b/flower/sstack.hh
new file mode 100644
index 0000000000..fa21392de0
--- /dev/null
+++ b/flower/sstack.hh
@@ -0,0 +1,30 @@
+/*
+  sstack.hh -- part of Flower lib
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef SSTACK_HH
+#define SSTACK_HH
+
+#include "vray.hh"
+
+/// A simple stack based on svec.
+template<class T>
+struct sstack : svec<T> { 
+    T top() { return last(); }
+    T pop() {
+	assert(!empty());
+	T l = last();
+        svec<T>::pop();
+	return l;
+    }
+    void push(T l) { add(l); }
+};
+/**
+  Same as for #svec# goes here.
+*/
+
+
+#endif // SSTACK_HH
+
diff --git a/flower/textstr.hh b/flower/textstr.hh
index c64a989c3c..63369ac258 100644
--- a/flower/textstr.hh
+++ b/flower/textstr.hh
@@ -3,10 +3,8 @@
 
 #include <stdio.h>
 #include <ctype.h>
-
-//#include "globals.hh"
 #include "string.hh"
-#include "vray.hh"
+#include "sstack.hh"
 
 /// line counting input stream.
 class Text_stream
diff --git a/flower/vray.hh b/flower/vray.hh
index ab6255109b..302499b256 100644
--- a/flower/vray.hh
+++ b/flower/vray.hh
@@ -156,21 +156,4 @@ public:
 
   */
 
-/// A simple stack based on svec.
-template<class T>
-class sstack : svec<T> {
- public:
-    T top() { return last(); }
-    T pop() {
-	assert(!empty());
-	T l = last();
-        svec<T>::pop();
-	return l;
-    }
-    void push(T l) { add(l); }
-    bool empty() { return svec<T>::empty(); } 
-};
-/**
-  Same as for #svec# goes here.
-*/
 #endif
diff --git a/hdr/clefitem.hh b/hdr/clefitem.hh
index f44dffcea6..f54d49306a 100644
--- a/hdr/clefitem.hh
+++ b/hdr/clefitem.hh
@@ -13,6 +13,8 @@
 struct Clef_item : Item {
     String type;
     int y_off;
+    bool change;
+
 
     Clef_item();
     void read(Clef);
diff --git a/hdr/debug.hh b/hdr/debug.hh
index fb3a070593..e86fe2247d 100644
--- a/hdr/debug.hh
+++ b/hdr/debug.hh
@@ -3,9 +3,10 @@
 #include <assert.h>
 #include <iostream.h>
 #include "dstream.hh"
+#include "real.hh"
 
 void error(String s);		// errors
-
+void error_t(String s, Real when);
 // warnings
 void warning(String s);
 #define WARN warnout << "warning: "<<__FUNCTION__ << "(): "
@@ -20,9 +21,10 @@ extern Dstream monitor; // monitor
 #ifdef NPRINT
 #define mtor if (0) monitor	// clever hack 
 #else
-#define mtor monitor.identify_as(__PRETTY_FUNCTION__)
+#define mtor if (check_debug) monitor.identify_as(__PRETTY_FUNCTION__)
 #endif
 
+extern bool check_debug;
 
 
 #endif
diff --git a/hdr/getcommand.hh b/hdr/getcommand.hh
new file mode 100644
index 0000000000..b1af2699e2
--- /dev/null
+++ b/hdr/getcommand.hh
@@ -0,0 +1,8 @@
+Command*get_clef_interpret_command(String w);
+Command *get_bar_command(Real);
+Command* get_meterchange_command( int,int);
+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);
diff --git a/hdr/identifier.hh b/hdr/identifier.hh
index 9cb80386c0..f1d99678d9 100644
--- a/hdr/identifier.hh
+++ b/hdr/identifier.hh
@@ -18,7 +18,7 @@ struct Identifier
     Identifier(String n) ;
     virtual ~Identifier();
     virtual Staff * staff() { assert(false); }
-    virtual Voice * voice() { assert(false); }
+    virtual Voice_list * voices() { assert(false); }
 };
 
 struct Staff_id : Identifier {
@@ -27,10 +27,10 @@ struct Staff_id : Identifier {
     ~Staff_id();
 };
 
-struct Voice_id : Identifier {
-    Voice_id(String s, Voice*st):Identifier(s) { data = st; }
-    virtual Voice * voice() { return (Voice*)data; }
-    ~Voice_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();
 };
 #endif // IDENTIFIER_HH
 
diff --git a/hdr/inputcommands.hh b/hdr/inputcommands.hh
new file mode 100644
index 0000000000..8222f9b74f
--- /dev/null
+++ b/hdr/inputcommands.hh
@@ -0,0 +1,64 @@
+/*
+  inputcommands.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef INPUTCOMMANDS_HH
+#define INPUTCOMMANDS_HH
+#include "pcursor.hh"
+#include "proto.hh"
+#include "plist.hh"
+#include "real.hh"
+
+struct Input_cursor : public PCursor<Command*>
+{
+    /// current measure info
+    Real whole_per_measure;
+
+    /// where am i 
+    Real whole_in_measure;
+
+    /// Real last when which was read
+    Real last;
+    
+    int bars;
+    
+    Input_cursor(PCursor<Command*>);
+    /// hmm. not safe. Should rethink cursor.
+    void operator++(int);
+    /** warning: no optor -- () defined.. */
+    void reset();
+    Real when()const;
+    void add(Command*);
+    void setpartial(Real);
+    void addbot(Command*);
+    void sync();
+    void print()const;   
+    void last_command_here();
+};
+
+/// the list of commands in Score
+struct Input_commands : public IPointerList<Command*> {
+    Input_cursor ptr;
+
+    /****************/
+
+    void find_moment(Real);
+    void do_skip(int & bars, Real & wholes);
+    void truncate(Real);
+    
+    Input_commands();
+    Input_commands(Input_commands const&);
+    void add(Command*);
+    void reset();
+    void print()const;
+    Staff_commands *parse() const;
+};
+
+
+void
+interpret_meter(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
new file mode 100644
index 0000000000..d5bf580fc6
--- /dev/null
+++ b/hdr/inputmusic.hh
@@ -0,0 +1,80 @@
+/*
+  inputmusic.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef INPUTMUSIC_HH
+#define INPUTMUSIC_HH
+
+#include "plist.hh"
+#include "proto.hh"
+
+struct Voice_list : public PointerList<Voice*> {
+    void translate_time(Real dt);
+    /// delete stuff; not in destructor!
+    void junk();
+};
+
+struct Vertical_music {
+    virtual Vertical_simple *simple() { return 0;}
+    virtual Voice_list convert()=0;
+    virtual Real length()=0;
+    virtual void translate_time(Real dt)=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);
+
+};
+
+struct Vertical_simple : Vertical_music {
+    Voice * voice_;
+    
+    /****************/
+    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);
+};
+
+struct Music_voice : Horizontal_music {
+    PointerList<Vertical_music*> voice_ ;
+    
+    /****************/
+
+    Real length();
+    void add(Vertical_music*);
+    void add(Voice_element*);
+    virtual Voice_list convert();
+    virtual void translate_time(Real dt);
+};
+
+struct Music_general_chord : Vertical_music {
+    PointerList<Horizontal_music*> chord_;
+
+    /****************/
+    void add(Horizontal_music*);
+    virtual Real length();
+    virtual Voice_list convert();
+    virtual void translate_time(Real dt);
+};
+
+
+#endif // INPUTMUSIC_HH
diff --git a/hdr/lexer.hh b/hdr/lexer.hh
index e2537da410..f1cddd1e27 100644
--- a/hdr/lexer.hh
+++ b/hdr/lexer.hh
@@ -7,7 +7,7 @@ void new_input(String s);
 bool close_input();
 int yylex();
 void yyerror(const char *s);
-
+bool busy_parsing();
 int lookup_keyword(String s);
 
 Identifier* lookup_identifier(String s);
diff --git a/hdr/linestaff.hh b/hdr/linestaff.hh
index 891269dd9d..c11d781a14 100644
--- a/hdr/linestaff.hh
+++ b/hdr/linestaff.hh
@@ -6,6 +6,6 @@ struct Linestaff : PStaff {
 
 /****************/
     
-    Symbol get_stafsym(Real width)const;
+    void brew_molecule(Real width);
     Linestaff(int, PScore*);   
 };
diff --git a/hdr/lookup.hh b/hdr/lookup.hh
index 14ed92f6b8..29b4aa9c5b 100644
--- a/hdr/lookup.hh
+++ b/hdr/lookup.hh
@@ -12,7 +12,7 @@ struct Lookup {
     /****************/
     Real internote();
     void parse (Text_db&t);
-    Parametric_symbol *linestaff(int n);
+    Symbol linestaff(int n, Real w);
 
     Symbol beam_element(int,int,Real=0);
     /// round slope to closest TeXslope
diff --git a/hdr/main.hh b/hdr/main.hh
index 58928f5142..5bd2a545f2 100644
--- a/hdr/main.hh
+++ b/hdr/main.hh
@@ -3,6 +3,7 @@
 #include "proto.hh"
 
 void debug_init();
+void set_debug(bool);
 void do_scores();
 void add_score(Score * s);
 void set_default_output(String s);
diff --git a/hdr/melodicstaff.hh b/hdr/melodicstaff.hh
index d97bfb17f8..c908f1dcb0 100644
--- a/hdr/melodicstaff.hh
+++ b/hdr/melodicstaff.hh
@@ -15,6 +15,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*);
diff --git a/hdr/molecule.hh b/hdr/molecule.hh
index 35060bd92a..83f8ac1e2c 100644
--- a/hdr/molecule.hh
+++ b/hdr/molecule.hh
@@ -5,11 +5,14 @@
 #include "boxes.hh"
 #include "item.hh"
 #include "symbol.hh"
+
 /// a symbol which can be translated, and freely copied
 struct Atom {
     Offset off;
     Symbol sym;
 
+    /****************/
+    
     void translate(Offset o) {
 	off += o;
     }
@@ -18,7 +21,7 @@ struct Atom {
     Box extent() const;
     Atom(Symbol s);
 
-  void print() const;
+    void print() const;
 
     String TeXstring() const;
 };
@@ -27,6 +30,8 @@ struct Atom {
 struct Molecule {
     IPointerList<Atom*> ats;
 
+    /****************/
+    
     Molecule() { }
     Molecule(Atom a) { add(a) ; }
 
diff --git a/hdr/notehead.hh b/hdr/notehead.hh
index b694e95af8..3137a1e558 100644
--- a/hdr/notehead.hh
+++ b/hdr/notehead.hh
@@ -12,18 +12,23 @@
 struct Notehead : public Item
 {
     int position;
+
+    /// needed for the help-lines
     int staff_size;
     int dots;
     int balltype;
 
     /****************/
+    
     void preprocess();
 
     Notehead(int staff_size);
     /**
       position of top line (5 linestaff: 8)
       */
+    
     void print()const;
+
 private:
     void brew_molecole();
 };
diff --git a/hdr/parseconstruct.hh b/hdr/parseconstruct.hh
index 81401852bc..ab50c15a1b 100644
--- a/hdr/parseconstruct.hh
+++ b/hdr/parseconstruct.hh
@@ -1,19 +1,11 @@
 #include "proto.hh"
 
-template<class T>
-struct svec;
-
 void set_default_duration(String);
 void set_default_pitch(String);
 Staff * get_new_rhythmstaff();
 Voice_element * get_note_element(String,String);
 Voice_element* get_rest_element(String,String);
-Command *  get_bar_command(Real);
 Staff * get_new_melodicstaff();
 void add_requests( Voice_element*v, svec<Request*>&req);
-Command* get_meterchange_command( int,int);
-Command* get_meter_command( Real,int,int);
-Command* get_skip_command( int,Real);
-Command* get_key_interpret_command(svec<String>);
 Request* get_request(char);
-Command*get_clef_interpret_command(String w);
+
diff --git a/hdr/proto.hh b/hdr/proto.hh
index 33d6f8e27a..065424b7c9 100644
--- a/hdr/proto.hh
+++ b/hdr/proto.hh
@@ -1,3 +1,4 @@
+
 /*
   proto.hh -- part of LilyPond
 
@@ -6,96 +7,84 @@
 
 #ifndef PROTO_HH
 #define PROTO_HH
+
+#include "fproto.hh"
 #include "real.hh"
 
-class Line_of_score;
-class Line_of_staff;
-class PCol;
-class PStaff;
-class Staff;
-class Staff_column;
-class Score;
-class Score_column;
-class Voice;
-class Voice_element;
-class Voicegroup;
-class Request;
-class Command;
-class Request;
-class Stem_req;
-class Span_req;
-class Slur_req;
-class Decresc_req;
-class Cresc_req;
-class Bracket_req;
-class Script_req;
-class Rest_req;
-class Note_req;
-class Lyric_req;
-class Chord;
-class Absdynamic_req;
-struct Offset;
-struct Interval;
+
+struct Absdynamic_req;
+struct Accidental;
+struct Atom;
+struct Beam;
+struct Beam_req;
 struct Box;
-struct PCol;
+struct Bracket_req;
+struct Chord;
+struct Clef;
+struct Clef_item;
+struct Colinfo;
+struct Command;
+struct Cresc_req;
+struct Decresc_req;
+struct Dynamic;
 struct Idealspacing;
-struct Spanner;
+struct Identifier;
+struct Input_commands;
+struct Interval;
 struct Item;
+struct Key;
+struct Keyitem;
+struct Keyword;
+struct Line_of_score;
 struct Line_of_staff;
-struct Colinfo;
 struct Linestaff;
-struct Atom;
+struct Local_key;
+struct Local_key_item;
+struct Lookup;
+struct Lyric_req;
+struct Mixed_qp;
 struct Molecule;
+struct Note_req;
+struct Notehead;
+struct Offset;
+struct Output;
+struct PCol;
 struct PScore;
+struct PStaff;
+struct Paperdef;
+struct Parametric_symbol;
 struct Request;
-struct Note_req;
-struct Lyric_req;
-struct Script_req;
+struct Rest;
 struct Rest_req;
 struct Rhythmic_req;
-struct Chord;
-struct Stem_req;
-struct Span_req;
-struct Beam_req;
-struct Bracket_req;
-struct Slur_req;
-struct Dynamic;
-struct Cresc_req;
-struct Decresc_req;
-struct Absdynamic_req;
-struct Score_column;
 struct Score;
-struct Staff_column;
+struct Score_column;
+struct Staff_commands;
+struct Script_req;
+struct Slur;
+struct Slur_req;
+struct Span_req;
+struct Spanner;
 struct Staff;
-struct Command;
+struct Staff_column;
+struct Stem;
+struct Stem_req;
+struct String;
 struct Symbol;
-struct Output;
+struct Symtable;
+struct Symtables;
+struct Tex_stream;
 struct Text_gob;
 struct Voice;
-struct Voicegroup;
 struct Voice_element;
-struct String;
-struct Tex_stream;
-struct Identifier;
-struct Keyword;
-class Mixed_qp;
-class Paperdef;
-class Score_commands;
-class Parametric_symbol;
-struct Lookup;
-struct Symtables;
-struct Symtable;
-struct Stem;
-struct Notehead;
-struct Beam;
-struct Rest;
-struct Accidental;
-struct Key;
-struct Local_key;
-struct Keyitem;
-struct Local_key_item;
-struct Clef;
-struct Clef_item;
-struct Slur;
-#endif // PROTO_HH
+struct Voicegroup;
 
+struct Voice_list;
+struct Vertical_music;
+struct Horizontal_music;
+struct Horizontal_simple;
+struct Vertical_simple ;
+struct Music_voice;
+struct Music_general_chord;
+
+#endif // PROTO_HH
diff --git a/hdr/pstaff.hh b/hdr/pstaff.hh
index d3057af5e9..6d0bdcf341 100644
--- a/hdr/pstaff.hh
+++ b/hdr/pstaff.hh
@@ -5,9 +5,9 @@
 #include "item.hh"
 #include "symbol.hh"
 
-/// items grouped vertically.
+/// items grouped horizontally
 struct PStaff {
-    Parametric_symbol *stafsym;
+    Molecule * stafsym;
     PScore * pscore_;
     
     
@@ -15,10 +15,10 @@ struct PStaff {
     PointerList<Item*> its;
 
     /****************/
-    virtual Symbol get_stafsym(Real width)const=0; // maybe overkill
+    virtual void brew_molecule(Real width)=0; // maybe overkill
     void add(Item*i);
     PStaff(PScore*);
-    virtual ~PStaff() {}
+    virtual ~PStaff();
 };
 
 #endif
diff --git a/hdr/scommands.hh b/hdr/scommands.hh
deleted file mode 100644
index 110c656368..0000000000
--- a/hdr/scommands.hh
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-  lilypond, (c) 1996 Han-Wen Nienhuys
-*/
-#ifndef SCOMMANDS_HH
-#define SCOMMANDS_HH
-
-#include "proto.hh"
-#include "command.hh"
-#include "vray.hh"
-#include "plist.hh"
-
-/// the list of commands in Score
-struct Score_commands : public IPointerList<Command*> {
-    void process_add(Command);
-    Score_commands*parse(Real last)const;
-    void parser_add(Command*);
-    void add_seq(svec<Command>,bool);
-    void clean(Real last);
-    void set_breakable(Real when);
-    bool is_breakable(Real w);
-    PCursor<Command*> last_insertion(Real w);
-    PCursor<Command*> first(Real w);
-    void add_command_to_break(Command pre, Command mid,Command post);
-    void OK() const;
-    void print() const;
-    Real last() const;
-    void insert_between(Command victim, PCursor<Command*> firstc,
-			PCursor<Command*> last);
-};
-/** the list of commands in Score. Put in a separate class, since it
-  otherwise clutters the methods of Score.
-
-  This class serves two purposes: it stores the commands (via
-  parser_add()) in the yacc parser. at a later stage, some 'high
-  level' commands are converted (method: parse())  
-  */
-
-#endif
-
diff --git a/hdr/score.hh b/hdr/score.hh
index ea1ef93c23..20a4d75da8 100644
--- a/hdr/score.hh
+++ b/hdr/score.hh
@@ -10,25 +10,27 @@ struct Score {
     /// paper_, staffs_ and commands_ form the problem definition.
     Paperdef *paper_;
     IPointerList<Staff*> staffs_;
-    Score_commands *commands_;
+
+    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();    
     void add(Staff*);        
-    void set(Score_commands*);
+
 
 
     void OK() const;
-    Score_column *find_col(Real,bool);
+    PCursor<Score_column *> find_col(Real,bool);
     void process();
     void output(String fn);
     PCursor<Score_column*> create_cols(Real);
@@ -39,8 +41,9 @@ private:
     void do_pcols();    
     void clean_cols();
     void distribute_commands();
-    void do_connect(PCol *c1, PCol *c2, Real d);
-    void connect_nonmus(PCol* c1, PCol *c2, Real d);
+    void do_connect(PCol *c1, PCol *c2, Real d,Real);
+    void connect(PCol* c1, PCol *c2, Real d,Real = 1.0);
+    
     /// add #Idealspacings# to #pscore_#
     void calc_idealspacing();
     /** add the score wide commands (bars, breaks) to each staff so
diff --git a/hdr/scoreline.hh b/hdr/scoreline.hh
index 5ebb936b1e..e3997b5a36 100644
--- a/hdr/scoreline.hh
+++ b/hdr/scoreline.hh
@@ -20,7 +20,7 @@ Line_of_score {
     PScore * pscore_;	// needed to generate staffs
 
     /****************/
-    
+    void process() ;
     Line_of_score(svec<const PCol *> sv,  PScore *);
 
     String TeXstring() const;
diff --git a/hdr/staff.hh b/hdr/staff.hh
index a2ac99ed03..803bf87388 100644
--- a/hdr/staff.hh
+++ b/hdr/staff.hh
@@ -1,9 +1,7 @@
 #ifndef STAFF_HH
 #define STAFF_HH
 
-#include "score.hh"
-#include "voice.hh"
-#include "command.hh"
+#include "staffcommands.hh"
 
 
 /// base class for a collection of voices.
@@ -12,8 +10,8 @@ struct Staff {
     IPointerList<Voice*> voices;
 
     /// commands in chronological order
-    IPointerList<Command *> commands;
-
+    Staff_commands *staff_commands_;
+    
     /// runtime field
     IPointerList<Staff_column*> cols;
 
@@ -21,7 +19,13 @@ 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);
+    
     Staff(const Staff&src);
     void add_voice(Voice *v);
     void add_staff_column(Staff_column *sp);
@@ -40,14 +44,6 @@ struct Staff {
     void clean_cols() ;
     Staff_column * get_col(Real,bool);
 
-    void add_commands(PointerList<Command* >const & sv);
-    /**
-    add all commands from sv.
-
-    PRE
-    sv is time-ordered.
-    */
-
     Staff();
     /**
       Should construct with Score as arg, but this isn't known during parsing.      
diff --git a/hdr/staffcommands.hh b/hdr/staffcommands.hh
new file mode 100644
index 0000000000..b7cdef0f9b
--- /dev/null
+++ b/hdr/staffcommands.hh
@@ -0,0 +1,37 @@
+/*
+  lilypond, (c) 1996 Han-Wen Nienhuys
+*/
+#ifndef SCORECOMMANDS_HH
+#define SCORECOMMANDS_HH
+
+#include "proto.hh"
+#include "command.hh"
+#include "vray.hh"
+#include "plist.hh"
+
+/// the list of commands in Score
+struct Staff_commands : public IPointerList<Command*> {
+    void process_add(Command);
+    void add_seq(svec<Command>,bool);
+    void clean(Real last);
+    void set_breakable(Real when);
+    bool is_breakable(Real w);
+    PCursor<Command*> last_insertion(Real w);
+    PCursor<Command*> first(Real w);
+    void add_command_to_break(Command pre, Command mid,Command post);
+    void OK() const;
+    void print() const;
+    Real last() const;
+    void insert_between(Command victim, PCursor<Command*> firstc,
+			PCursor<Command*> last);
+};
+/** the list of commands in Score. Put in a separate class, since it
+  otherwise clutters the methods of Score.
+
+  This class serves two purposes: it stores the commands (via
+  parser_add()) in the yacc parser. at a later stage, some 'high
+  level' commands are converted (method: parse())  
+  */
+
+#endif
+
diff --git a/hdr/staffline.hh b/hdr/staffline.hh
index 868198b013..12d30c3764 100644
--- a/hdr/staffline.hh
+++ b/hdr/staffline.hh
@@ -17,14 +17,14 @@
 struct Line_of_staff {
 
     Line_of_score  * line_of_score_;
-    const PStaff *pstaff_;
+    PStaff *pstaff_;
 
     /****************/
     
     String TeXstring() const;
     Line_of_staff(Line_of_score*, PStaff *);
     Interval height() const;
-
+    void process();
 };
 
 #endif
diff --git a/hdr/symbol.hh b/hdr/symbol.hh
index 4f26e04e66..3c664dfbaa 100644
--- a/hdr/symbol.hh
+++ b/hdr/symbol.hh
@@ -12,16 +12,4 @@ struct Symbol {
     Symbol();
 };
 
-struct Parametric_symbol {    
-    Symtables*symtables_;	// indirection 
-
-    /*****************/
-    
-    Parametric_symbol(Symtables*s) { symtables_ = s; }
-    Symbol eval(String args1) const; // convenience
-    Symbol eval(String args1,String arg2) const; // convenience
-    virtual Symbol eval(svec<String> args)const =0;
-    virtual ~Parametric_symbol(){}
-};
-
 #endif
diff --git a/hdr/voice.hh b/hdr/voice.hh
index db2e0872cf..c716c650dc 100644
--- a/hdr/voice.hh
+++ b/hdr/voice.hh
@@ -1,9 +1,8 @@
 #ifndef VOICE_HH
 #define VOICE_HH
 
-
+#include "proto.hh"
 #include "plist.hh"
-#include "request.hh"
 
 /// class for  horizontal stuff.
 struct Voice {
@@ -36,9 +35,6 @@ struct Voice_element {
     const Voice *voice_;
     IPointerList<Request*> reqs;
 
-   PointerList<const Item *> granted_items;
-    PointerList<const Spanner *> granted_spanners;
-
     /****************/
     
     void add(Request*);
diff --git a/kortjakje.ly b/kortjakje.ly
index c4c20cf1b7..86835bf3b5 100644
--- a/kortjakje.ly
+++ b/kortjakje.ly
@@ -2,46 +2,46 @@
 % 
 % bare bones version. (written down from memory :-)
 
-melodie = voice {
-	$ \octave c
+melodie = $ \octave {c}
 	%%% theme
-	  c c	g g	a a	g2	f f	e e	d d  c2
+	  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 = voice {
-	$ \octave `c
+begeleiding = $
+	\octave {`c}
 	%%% theme
 	`c c	e c	f c	e c	d `b	c `a	`f `g	`c2
-	\octave `c
+	\octave {`c}
 	e `g	d `g	c `g	`b `g	e `g	d `g	c `g	`b `g
 	%%%% 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
-	$
-}
+$
 
 
-score {
-	melodicstaff {
-		voice { melodie }
+bstaf = melodicstaff {
+		voices { begeleiding }
+		commands {
+			clef bass
+		}
 	}
-	melodicstaff {
-		voice { begeleiding }
+vstaf = melodicstaff {
+		voices { melodie }
 	}
+
+
+score {
+	staff { vstaf }
+	staff { bstaf }
 	paper {
-		unitspace 2.5cm
+%		unitspace 2.5cm
 	}
 	commands {
-		meter 2 4
-		clef bass
-		skip 2:0
-		clef violin
-%		skip 2:0
+		meter 2 4 
 		skip 32:0
 	}
 }
diff --git a/lilyponddefs.tex b/lilyponddefs.tex
index 1e098eb271..152d461d64 100644
--- a/lilyponddefs.tex
+++ b/lilyponddefs.tex
@@ -59,8 +59,11 @@
 \mdef\doubledot{'01}
 \mdef\tripledot{'02}
 \mdef\mussepline{155}
+
 \mdef\violinclef{71}
 \mdef\bassclef{73}
+\mdef\cviolinclef{72}
+\mdef\cbassclef{74}
 
 \mdef\deigthflag{45}
 \mdef\dsixteenthflag{46}
diff --git a/maartje.ly b/maartje.ly
index fcb64323ee..c1dd45a689 100644
--- a/maartje.ly
+++ b/maartje.ly
@@ -1,35 +1,48 @@
 ritme = rhythmstaff {
-	voice { $ c2 c2
+	$
+	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 {
-	voice { $ c () `bes $ start 0.5 }	
-	voice { $
-	%[fis16 'dis16 fis16 'dis16 fis16 'dis16 fis16 'dis16]
-	c2
-	'fis ()'gisis $ }
+	$
+	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 }
+	}
+	c4
 
-	voice {  $ d () d $ start 0.5 }
-	voice {  $ a  () bes $ start 0.5 }
-	voice {  $ fis () g $ start 0.5 }
-	
-
-  voice { $
-	''c2.. r8 r4 r8 r16 r32 r32
-	[d8 e8 'f8 g8] [d8 e8 f8 g8]
-	''fis1
+	[d8 e8 'f8 g8]  d8 e8 f8 g8
+	''fis2
 	a8 b8 'c8 'd8 ''c8 ```c8 c4 c4  c4 c4
-	\duration 16  `b16 `a16 `g16 `f16 \duration 4
-	c `b `a `g `f `e `d `c ``b ``a ``g ``f ``e ``d ``c$
-	start 1.0 }
+	\duration{ 16 } `b `a `g `f \duration{ 4}
+	c `b `a `g `f `e `d `c ``b ``a ``g ``f ``e ``d ``c
+	$
+
+
+commands {
+	skip 2:0
+	key $ fis cis gis $
+	skip 2:0
+	key $ $
+	skip 5:0
+	clef bass
+}
 }
+
 score {
 	paper {
 		geometric 1.4
@@ -39,10 +52,10 @@ score {
 	staff { melody }
 %	staff { melody }
 	commands {
+		partial 0.125 skip 0:0.125
+
 		meter 4 4
-		key $ fis cis gis $
-		skip 2:0
-		key $ $
+		skip 2:0		
 		meter 2 4
 		skip 19:0
 	}
diff --git a/pavane.ly b/pavane.ly
new file mode 100644
index 0000000000..e58508cb98
--- /dev/null
+++ b/pavane.ly
@@ -0,0 +1,58 @@
+% pavane pour une Infante d\'efunte
+% 
+% M. Ravel
+%
+% (Ravel has been dead for over 50 years. This does not have copyright)
+%
+
+horn = melodicstaff {
+	$
+	\octave { 'c }
+	\duration { 8}
+
+% 1
+	d2( [)d e cis `b]		`a4 [`b cis] [cis `b] `b4
+	fis2( [)fis g e d] 		cis4 [d e(] [)e fis d cis]
+	`b4 [cis d(] [)d e cis `b] 	cis2 r2
+	r4 fis2 fis4 			fis2()[fis e a fis]
+	fis4 e4 d4 e4 			`b2()[`b `a( d cis]
+% 11
+	)`b [`fis `a `b] cis4 `b4	`fis2 r2
+	cis4 d4()[d cis d e]
+\octave { c }
+					a4 gis2.
+	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]
+	fis4 e4 cis2			e4 fis4()[fis e fis gis]
+	cis4 `b4()`b8 r8 r4		r1
+	r2 r4 r4			
+%% cut 'n paste.
+	\octave { 'c }
+	d2( [)d e cis `b]		`a4 [`b cis] [cis `b] `b4
+	fis2( [)fis g e d] 		cis4 [d e(] [)e fis d cis]
+	`b4 [cis d(] [)d e cis `b] 	cis2 r2
+	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 {
+		key  $fis cis $
+	}
+}
+
+score {
+	staff { horn }
+	paper { unitspace 2.2 cm
+		geometric 1.5
+	}
+	commands { meter 4 4
+		skip 18:0
+		meter 2 4
+		skip 1:0
+		meter 4 4 
+		skip 20:0
+	}
+}
\ No newline at end of file
diff --git a/src/beam.cc b/src/beam.cc
index f8ca8b5ab8..6eb4d07813 100644
--- a/src/beam.cc
+++ b/src/beam.cc
@@ -92,15 +92,6 @@ Beam::solve_slope()
     left_pos *= dir;    
     slope *= dir;
     
-    {
-	Real inter =paper()->internote();
-	Real unitslope = slope*inter;
-
-	// set beamslope, for setting stems correctly
-	// ignoring return.
-	Symbol sy = paper()->lookup_->beam(unitslope, width().length());
-	slope =unitslope / inter;
-    }
 }
 
 void
@@ -122,7 +113,6 @@ Beam::calculate()
 	set_default_dir();
 
     solve_slope();
-    set_stemlens();
 }
 
 void
@@ -130,6 +120,7 @@ Beam::process()
 {
     calculate();
     brew_molecule();
+    set_stemlens();
 }
 
 
@@ -169,7 +160,8 @@ Beam::brew_molecule()
     Real sl = slope*inter;
     Real w =  width().length() + paper()->rule_thickness();
     Symbol s = paper()->lookup_->beam(sl,w);
-
+    slope = sl / inter;
+    
     Atom a(s);
     
     Real dx = width().min -left->hpos;
diff --git a/src/calcideal.cc b/src/calcideal.cc
index 03910ac561..3f9a7dca23 100644
--- a/src/calcideal.cc
+++ b/src/calcideal.cc
@@ -5,37 +5,33 @@
 #include "paper.hh"
 #include "sccol.hh"
 #include "debug.hh"
+#include "dimen.hh"
 
 
 void
-Score::do_connect(PCol *c1, PCol *c2, Real d)
+Score::do_connect(PCol *c1, PCol *c2, Real d, Real h)
 {
+    if (!c1 || !c2 )
+	return;
     Idealspacing*sp=pscore_->get_spacing(c1,c2);
 	
     if (!sp->hooke){
-	sp->hooke = 1.0;
+	sp->hooke = h;
 	sp->space =d;
     }
 }
 
 void
-Score::connect_nonmus(PCol* c1, PCol *c2, Real d)
+Score::connect(PCol* c1, PCol *c2, Real d, Real h)
 {
     if (c2->used() && c1->used()) {
-	do_connect(c1,c2,d);
-
-	// alert! this is broken!
-	if (c1->breakable()) {
-	    do_connect(c1->postbreak, c2,d);
-	}
-	if (c2->breakable()) {
-	    do_connect(c1, c2->prebreak,d);
-	}
-	if (c1->breakable() &&c2->breakable()) {
-	    do_connect(c1->postbreak, c2->prebreak,d);	    
-	}	
+	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.
 
     generate springs between columns.
@@ -43,21 +39,41 @@ Score::connect_nonmus(PCol* c1, PCol *c2, Real d)
 void
 Score::calc_idealspacing()
 {
-    PCursor<Score_column*> sc(cols_);
+    PCursor<Score_column*> i(cols_);
 
-    for (; sc.ok(); sc++) {
-	if (sc->musical)
-	    for (int i=0; i < sc->durations.sz(); i++) {
-		Real d = sc->durations[i];
+    for (; i.ok(); i++) {
+		
+	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);
-		PCol * c2 = find_col(sc->when + d,true)->pcol_;
-		connect_nonmus(sc->pcol_, c2, dist);
-		c2 = find_col(sc->when + d,false)->pcol_;
-		connect_nonmus(sc->pcol_, c2,  dist);
+		while (d + i->when > j->when)
+		    j++;
+
+		if (j->used())
+		    connect(i->pcol_, j->pcol_, dist);
+		if (!j->musical && (j+1)->used && (j+1)->when == j->when) {
+		    j++;
+		    connect(i->pcol_, j->pcol_,  dist);
+		}
+	    }
+	} else if (i->used()) {
+
+	    /* 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");
+
+		    connect(i->pcol_, j->pcol_, dist, (d) ? 1.0:1.0);
+		    break;
+		}
 	    }
-	else if (sc->used()) {	// ignore empty columns
-	    PCol * c2 = find_col(sc->when,true)->pcol_;
-	    connect_nonmus(sc->pcol_, c2, 0.0);
+	    // !j.ok() might hold if we're at the last col.
 	}
     }       	
 }
diff --git a/src/clefitem.cc b/src/clefitem.cc
index 796cda389e..3e10f88867 100644
--- a/src/clefitem.cc
+++ b/src/clefitem.cc
@@ -7,6 +7,7 @@
 
 Clef_item::Clef_item()
 {
+    change = true;
     read("violin");
 }
 void
@@ -27,7 +28,10 @@ Clef_item::read(Clef k)
 void
 Clef_item::preprocess()
 {
-    Symbol s = paper()->lookup_->clef(type);
+    String t = type;
+    if  (change)
+	t += "_change";
+    Symbol s = paper()->lookup_->clef(t);
     output = new Molecule(Atom(s));
     output->translate(Offset(0, paper()->interline()/2 * y_off));
 }
diff --git a/src/debug.cc b/src/debug.cc
index d55c901945..7620027c91 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -25,3 +25,11 @@ debug_init()
     set_new_handler(&mynewhandler);
     set_matrix_debug(monitor);
 }   
+
+bool check_debug=false;
+
+void
+set_debug(bool b)
+{
+    check_debug =b;
+}
diff --git a/src/getcommands.cc b/src/getcommands.cc
index 04170f582a..c3b6bba692 100644
--- a/src/getcommands.cc
+++ b/src/getcommands.cc
@@ -2,6 +2,24 @@
 #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)
diff --git a/src/identifier.cc b/src/identifier.cc
index 024fe06486..40281ce718 100644
--- a/src/identifier.cc
+++ b/src/identifier.cc
@@ -2,6 +2,7 @@
 #include "identifier.hh"
 #include "staff.hh"
 #include "lexer.hh"
+#include "inputmusic.hh"
 
 
 Identifier::Identifier(String n)
@@ -20,7 +21,8 @@ Staff_id::~Staff_id()
     delete staff();
 }
 
-Voice_id::~Voice_id()
+Voices_id::~Voices_id()
 {
-    delete voice();
+    voices()->junk();
+    delete voices();
 }
diff --git a/src/inputcommands.cc b/src/inputcommands.cc
new file mode 100644
index 0000000000..2372a0ff14
--- /dev/null
+++ b/src/inputcommands.cc
@@ -0,0 +1,176 @@
+/*
+  it still sucks.
+  */
+
+#include "inputcommands.hh"
+#include "debug.hh"
+#include "staffcommands.hh"
+#include "getcommand.hh"
+#include "command.hh"
+
+Input_commands::Input_commands(Input_commands const&src)
+    : ptr(src.ptr)
+{
+    IPointerList<Command*> &me(*this);
+    const IPointerList<Command*> &that(src);
+    
+    PL_copy(me, that);    
+}
+
+Input_commands::Input_commands()
+    :    ptr (bottom())
+{
+    Command c(0.0);		
+    bottom().add(new Command(c));    
+    ptr = bottom();    
+}
+
+void
+Input_commands::truncate(Real last)
+{
+    bool reset_ = false;
+    
+    if (ptr.when() >= last)
+	reset_=true;
+    PCursor<Command*> i(*this);
+    
+    while (i.ok() && i ->when < last)
+	i++;
+
+    while (i.ok())
+	i.del();
+
+    if (reset_) {
+	reset();
+	
+	while(ptr.ok())
+	    ptr++;	
+    }
+}
+
+/*
+  ugh. This sux.
+  */
+void
+Input_commands::find_moment(Real w)
+{
+    assert(w >= ptr.when());
+    while (ptr.ok() && ptr.when() < w) {
+	ptr++;
+    }
+    
+    if (!ptr.ok()) {
+	int bars_left =int(floor( (w - ptr.last + ptr.whole_in_measure)
+				  /ptr.whole_per_measure));
+	if (bars_left) {
+	    Real bar_when = ptr.last - ptr.whole_in_measure + ptr.whole_per_measure;
+	    ptr.addbot(get_bar_command(bar_when));
+	    find_moment(w);	// tail-recursion. todo
+	} else {
+	    ptr.addbot(new Command(w));
+	}
+
+    } else if (ptr.when() != w) {
+	ptr.insert(new Command(w));
+	ptr--;	
+    }
+}
+
+void
+Input_commands::do_skip(int & bars, Real & wholes)
+{
+    if (wholes) {
+	find_moment(ptr.when() +wholes);
+	wholes = 0.0;	
+    }
+
+    if (bars) {
+	ptr.last_command_here(); // find any METER change commands.
+	if (ptr.whole_in_measure){
+	    Real barleft = ptr.whole_per_measure - ptr.whole_in_measure;
+	    do_skip(bars, barleft);
+	}else {
+	    find_moment(ptr.when() + bars*ptr.whole_per_measure);
+	    bars = 0;
+	}
+    }
+}
+
+
+void
+Input_commands::add(Command *c)
+{    
+    assert(c->code==INTERPRET);
+    if (c->args[0] == "PARTIAL") {
+	Real p = c->args[1].fvalue();
+	ptr.setpartial(p);
+	
+    } 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);
+	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();
+	while (bars > 0 || wholes > 0.0) {
+	    do_skip(bars, wholes);
+	}
+	delete c;
+    } else if (c->args[0] == "RESET") {
+	delete c;
+	
+	reset();	
+    }
+    
+}
+
+void
+Input_commands::reset()
+{
+    ptr = top();
+    ptr.reset();
+}
+
+
+Staff_commands*
+Input_commands::parse() const
+{
+    Staff_commands*nc = new Staff_commands;
+
+    {   /* all pieces should start with a breakable. */
+	Command c(0.0);
+	c.code = INTERPRET;
+	c.args.add("BAR");
+	c.args.add("empty");
+	nc->process_add(c);
+    }
+
+    for (PCursor<Command*> cc(*this); cc.ok(); cc++) {
+	if (cc->code != NOP)
+	    nc->process_add(**cc);
+    }
+    
+    return nc;
+}
+
+
+void
+Input_commands::print() const
+{
+#ifndef NPRINT
+    for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
+	cc->print();
+    }
+    ptr.print();
+#endif
+}
diff --git a/src/inputcursor.cc b/src/inputcursor.cc
new file mode 100644
index 0000000000..c6f4bfbabd
--- /dev/null
+++ b/src/inputcursor.cc
@@ -0,0 +1,115 @@
+/*
+  it still sucks.
+  */
+
+#include "inputcommands.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,
+		Real& whole_per_measure)
+{
+    beats_per_meas = c->args[1].value();
+    one_beat = c->args[2].value();
+    whole_per_measure = beats_per_meas/Real(one_beat);
+}
+
+Real
+Input_cursor::when()const
+{
+    return (*this)->when; 
+}
+
+void
+Input_cursor::print() const
+{
+#ifndef  NPRINT
+    mtor << "meter " << whole_per_measure
+	 << " pos "<< bars << ":" << whole_in_measure <<'\n';
+#endif
+}
+	
+void
+Input_cursor::reset()
+{
+    whole_per_measure = 1.0;	// ?
+    whole_in_measure =0.0;
+    bars = 0;
+    last=0;    
+}
+
+Input_cursor :: Input_cursor(PCursor<Command*>c)
+    :PCursor<Command*>(c)
+{
+    reset();    
+}
+
+void
+Input_cursor::sync()
+{
+    assert(ok());
+    
+    whole_in_measure += when() - last;
+    while (whole_per_measure > 0 && whole_in_measure >= whole_per_measure) {
+	bars ++;
+	whole_in_measure -= whole_per_measure;	
+    }
+    if (whole_in_measure < 1e-5) // ugr
+	whole_in_measure = 0.0;
+}
+
+void
+Input_cursor::operator++(int)
+{    
+    last = when();
+    (*(PCursor<Command*> *) this) ++;
+
+    if (ok()) {	
+	sync();
+	if (ptr()->code == INTERPRET && ptr()->args[0] == "METER") {
+	    int i,j;	    
+	    interpret_meter(ptr(), i, j, whole_per_measure);
+	}
+    }
+}
+
+void
+Input_cursor::addbot(Command*c)
+{
+    assert(!ok());    
+    add(c);
+}
+
+
+void
+Input_cursor::add(Command*c)
+{
+    PCursor<Command*> ::add(c);
+    (*this)++;
+}
+
+void
+Input_cursor::last_command_here()
+{
+    assert(ok());
+    PCursor<Command*> next = (*this)+1;
+    while (next.ok() && next->when == when()){
+	*this = next;
+	next = *this +1;
+	
+    }
+}
+
+void
+Input_cursor::setpartial(Real p)
+{
+    if (when())
+	error_t ("Partial measure only allowed at beginning.", when() );
+    if (p<0||p > whole_per_measure)
+	error_t ("Partial measure has incorrect size", when());
+
+    whole_in_measure = whole_per_measure - p;	
+}
diff --git a/src/inputmusic.cc b/src/inputmusic.cc
new file mode 100644
index 0000000000..b00835b95d
--- /dev/null
+++ b/src/inputmusic.cc
@@ -0,0 +1,147 @@
+#include "inputmusic.hh"
+#include "voice.hh"
+
+Vertical_simple::Vertical_simple()
+{
+    voice_ = new Voice;
+}
+
+void
+Vertical_simple::add(Voice_element*v)
+{
+    voice_->add(v);
+}
+
+Real
+Vertical_simple::length()
+{
+    return voice_->last();
+}
+void
+Vertical_simple::translate_time(Real t)
+{
+    voice_->start += t;
+}
+Voice_list
+Vertical_simple::convert()
+{
+    Voice_list l;
+    l.bottom().add(voice_);
+    return l;
+}
+
+    
+/****************/
+
+void
+Music_voice::add(Voice_element*v)
+{
+    PCursor<Vertical_music*> c(voice_.bottom());
+    if (!c.ok() || !c->simple()) {
+	Vertical_simple*vs = new Vertical_simple;
+	
+	c.add(vs);
+    }
+    
+    c = voice_.bottom();
+    Vertical_simple *s = c->simple();
+    s->add(v);    	    
+}
+
+void
+Music_voice::add(Vertical_music*v)
+{
+    //   v->translate_time(length());
+    voice_.bottom().add(v);
+}
+
+Real
+Music_voice::length()
+{
+    Real l = 0.0;
+    
+    for (PCursor<Vertical_music*> i(voice_); i.ok(); i++)
+	l += i->length();
+    return l;
+}
+
+    
+Voice_list
+Music_voice::convert()
+{
+    Voice_list l;
+    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.
+	Voice_list k(i->convert());
+	k.translate_time(here);	
+	l.concatenate(k);
+	here +=len;
+	
+    }
+    return l;    
+}
+
+void
+Music_voice::translate_time(Real t)
+{
+    for (PCursor<Vertical_music*> i(voice_); i.ok(); i++) 
+	i->translate_time(t);
+}
+
+    
+    
+/****************/
+
+void
+Music_general_chord::translate_time(Real t)
+{
+    for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++) 
+	i->translate_time(t);    
+}
+
+    
+	
+Real
+Music_general_chord::length()
+{
+    Real l =0.0;
+    
+    for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++) 
+	l = MAX(l, i->length());
+    return l;
+}
+
+void
+Music_general_chord::add(Horizontal_music*h)
+{
+    chord_.bottom().add(h);
+}
+
+Voice_list
+Music_general_chord::convert()
+{
+    Voice_list l;
+    for (PCursor<Horizontal_music*> i(chord_); i.ok(); i++) {
+	Voice_list k(i->convert());
+	l.concatenate(k);
+    }
+    return l;
+}
+
+/****************/
+
+void
+Voice_list::translate_time(Real x)
+{
+    for (PCursor<Voice*> i(*this); i.ok(); i++)
+	i->start += x;    
+}
+
+void
+Voice_list::junk()
+{
+    for (PCursor<Voice*> i(*this); i.ok(); i++)
+	delete i.ptr();
+}
diff --git a/src/lexer.l b/src/lexer.l
index 14892c3406..ab97197fa9 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -80,17 +80,21 @@ REAL		[0-9]+(\.[0-9]*)?
 }
 <notes>[ \t\n]+		{
 }
-<notes>%.*		{
+<notes>%.*$		{
 
 }
 <notes>\$	{
 	BEGIN(INITIAL); return '$';
 }
-<notes>[\[{)]	{ /* parens () are NO mistake */
+<notes>[{}]	{
+	return YYText()[0];
+	
+}
+<notes>[\[)]	{ /* parens () are NO mistake */
 	yylval.c = YYText()[0];
 	return OPEN_REQUEST_PARENS;
 }
-<notes>[\]}(]	{ /* parens () are NO mistake */
+<notes>[\](]	{ /* parens () are NO mistake */
 	yylval.c = YYText()[0];
 	return CLOSE_REQUEST_PARENS;
 }
@@ -166,6 +170,12 @@ REAL		[0-9]+(\.[0-9]*)?
 
 yyFlexLexer *lexer=0;
 
+bool
+busy_parsing()
+{
+    return lexer;	
+}
+
 // set the  new input to s, remember old file.
 void
 new_input(String s)
@@ -226,4 +236,5 @@ void
 kill_lexer()
 {
 	delete lexer;
+	lexer = 0;
 }
diff --git a/src/linestaff.cc b/src/linestaff.cc
index a52954e6f4..6d3985cb8b 100644
--- a/src/linestaff.cc
+++ b/src/linestaff.cc
@@ -1,4 +1,5 @@
 #include "linestaff.hh"
+#include "molecule.hh"
 #include "symbol.hh"
 #include "lookup.hh"
 #include "dimen.hh"
@@ -9,12 +10,18 @@ Linestaff::Linestaff(int l, PScore *s)
     : PStaff(s)
 {
     nolines = l;
-    stafsym = s->paper_->lookup_->linestaff(l); 
 }
 
-Symbol
-Linestaff::get_stafsym(Real width)const
-{  
-   String w(print_dimen(width));
-   return stafsym->eval(w);
+void
+Linestaff::brew_molecule(Real width)
+{
+    Atom a  = pscore_->paper_->lookup_->linestaff(nolines,width);
+    stafsym = new Molecule(a);    
 }
+
+
+
+
+
+
+
diff --git a/src/lookup.cc b/src/lookup.cc
index b9c369c0fc..018c57f9c0 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -102,27 +102,22 @@ Lookup::streepjes(int i)
 /****************************************************************/
 // bare bones.
 
-struct Linestaf_symbol : Parametric_symbol {
-    int lines;
-    Linestaf_symbol(int n, Symtables*s): Parametric_symbol(s) { lines = n;}
-    Symbol eval(svec<String>)const;
-};
-
 
 Symbol
-Linestaf_symbol::eval(svec<String> w)const
+Lookup::linestaff(int lines, Real wid) 
 {
-    Real wid = w[0].fvalue();
-
     Symbol s;
     s.dim.x = Interval(0,wid);
-    Real dy=(lines-1)*convert_dimen(5,"pt"); // TODO!
+    Real dy=(lines-1)*internote()*2;
     s.dim.y = Interval(0,dy);
+
     svec<String> a;
     a.add(lines);
-    a.add(w[0]);
+    a.add(print_dimen(wid));
+
     s.tex = (*symtables_)("param")->lookup("linestaf").tex;
     s.tex = substitute_args(s.tex, a);
+    
     return s;
 }
 
@@ -162,9 +157,3 @@ Lookup::stem(Real y1,Real y2)
 }
 
 
-Parametric_symbol *
-Lookup::linestaff(int n)
-{
-    return new Linestaf_symbol(n,symtables_);
-}
-
diff --git a/src/main.cc b/src/main.cc
index 8e499b0204..35f20603ba 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -11,6 +11,7 @@ long_option_init theopts[] = {
     1, "output", 'o',
     0, "warranty", 'w',
     0, "help", 'h',
+    0, "debug", 'd',
     0,0,0
 };
 
@@ -20,7 +21,10 @@ help()
     cout <<
 	"--help, -h		This help\n"
 	"--warranty, -w		show warranty & copyright\n"
-	"--output, -o		set default output\n";
+	"--output, -o		set default output\n"
+	"--debug, -d		enable debug output\n"
+	;
+    
 }
 void notice()
 {
@@ -64,6 +68,9 @@ main (int argc, char **argv)
 	    help();
 	    exit(0);
 	    break;
+	case 'd':
+	    set_debug(true);
+	    break;
 	default:
 	    assert(false);
 	    break;
diff --git a/src/melodicstaff.cc b/src/melodicstaff.cc
index 712ffb7e5f..a0c0b2e46f 100644
--- a/src/melodicstaff.cc
+++ b/src/melodicstaff.cc
@@ -9,6 +9,7 @@
 #include "rhythmstaff.hh"
 #include "sccol.hh" 
 #include "localkeyitem.hh"
+#include "request.hh"
 
 const int NO_LINES=5;
 
@@ -60,7 +61,14 @@ get_new_melodicstaff()
     return new Melodic_staff;
 }
 
-
+Rest*
+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()));
+    return r;
+}
 
 Melodic_staff*
 Melodic_staff::clone()const
diff --git a/src/note.cc b/src/note.cc
index 1c1a4cb571..f5911c0eda 100644
--- a/src/note.cc
+++ b/src/note.cc
@@ -34,16 +34,11 @@ parse_duration(const char *a, int &j, int &intdur, int &dots)
 }
 
 
-
-void 
-parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
-	     int & large, int & small)
-{
-    // octave
-    oct =default_octave;
-    
+void
+parse_octave (const char *a, int &j, int &oct)
+{    
     while (1) 
-	{	
+    {	
 	if (a[j] == '\'')
 	    oct ++;
 	else if (a[j] == '`')
@@ -51,10 +46,18 @@ parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
 	else
 	    break;
 	j++;
-	
-	}
+    }
+}
+
+void 
+parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
+	     int & large, int & small)
+{
+    // octave
+    oct =default_octave;
+    parse_octave(a,j,oct);
 
-	mtor << "oct " << oct;
+    mtor << "oct " << oct;
 	
     // accidental
     overide_acc = false;
@@ -152,9 +155,8 @@ void
 set_default_pitch(String d)
 {
     int i=0;
-    bool b;
-    int l,s;
-    parse_pitch(d, i, default_octave, b, l,s);
+    default_octave=0;
+    parse_octave(d, i, default_octave);
 }
 
 Request*
diff --git a/src/parser.y b/src/parser.y
index 376df8226d..abacc7add9 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -7,11 +7,12 @@
 #include "score.hh"
 #include "main.hh"
 #include "keyword.hh"
-#include "scommands.hh"
+#include "getcommand.hh"
 #include "debug.hh"
 #include "parseconstruct.hh"
 #include "dimen.hh"
 #include "identifier.hh"
+#include "inputmusic.hh"
 
 #ifndef NDEBUG
 #define YYDEBUG 1
@@ -25,7 +26,6 @@ svec<Request*> pre_reqs, post_reqs;
     Real real;
     Command *command;
     Identifier *id;    
-    Score_commands *scommands;
     Voice *voice;    
     Voice_element *el;	
     Staff *staff;    
@@ -34,15 +34,23 @@ svec<Request*> pre_reqs, post_reqs;
     const char *consstr;
     Paperdef *paper;
     Request* request;
+    Horizontal_music *horizontal;
+    Vertical_music *vertical;
+    Music_general_chord *chord;
+    Music_voice *mvoice; 
     int i;
     char c;
+
     svec<String> * strvec;
+    svec<Command*> *commandvec;
+    Voice_list *voicelist;
 }
 
 %token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
 %token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
 %token MELODICSTAFF GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
-%token KEY CLEF VIOLIN BASS
+%token KEY CLEF VIOLIN BASS MULTI TABLE CHORD VOICES
+%token PARTIAL
 
 %token <id>  IDENTIFIER
 %token <string> NEWIDENTIFIER 
@@ -57,17 +65,24 @@ svec<Request*> pre_reqs, post_reqs;
 %type <id> declaration 
 %type <paper> paper_block paper_body
 %type <real> dim
-%type <voice> voice_block voice_body voice_elts voice_elts_dollar
-%type <el> voice_elt
-%type <command> score_command
+
+%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 <i> int
-%type <scommands> score_commands_block score_commands_body
+%type <commandvec> score_commands_block score_commands_body
+%type <commandvec> staff_commands_block staff_commands_body
 %type <request> post_request pre_request
 %type <strvec> pitch_list
 %type <string> clef_id
+%type <vertical> vertical_music  
+%type <chord> music_chord music_chord_body
+%type <horizontal>  horizontal_music
+%type <mvoice>  music_voice_body music_voice
+%type <voicelist> voices
+
 %%
 
 mudela:	/* empty */
@@ -76,7 +91,9 @@ mudela:	/* empty */
 	}
 	| mudela add_declaration {	}
 	;
-
+/*
+	DECLARATIONS
+*/
 add_declaration: declaration	{
 		add_identifier($1);
 	}
@@ -87,31 +104,82 @@ declaration:
 		$$ = new Staff_id(*$1, $3);
 		delete $1; // this sux
 	}
-	| NEWIDENTIFIER '=' voice_block {
-		$$ = new Voice_id(*$1, $3);
+	| NEWIDENTIFIER '=' voices {
+		$$ = new Voices_id(*$1, $3);
 		delete $1;
 	}
 	;
 
 
+/*
+	SCORE
+*/
 score_block: SCORE '{' score_body '}' 	{ $$ = $3; }
 	;
 
 score_body:		{ $$ = new Score; } 
 	| score_body staff_block	{ $$->add($2); }
-	| score_body score_commands_block 	{ $$->set($2); }
+	| score_body score_commands_block 	{
+		$$->add(*$2);
+		delete $2;
+	}
 	| score_body paper_block		{ $$->set($2);	}
 	;
+/*
+	COMMANDS
+*/
 score_commands_block:
 	COMMANDS '{' score_commands_body '}' { $$ =$3;}
 	;
 
-score_commands_body:			{ $$ = new Score_commands; }
+score_commands_body:			{ $$ = new svec<Command*>; }
 	| score_commands_body score_command		{
-		$$->parser_add($2);
+		$$->add($2);
+	}
+	;
+
+staff_commands_block: COMMANDS '{' staff_commands_body '}'	{
+		$$ = $3; }
+	;
+
+staff_commands_body:
+	/* empty */			{ $$ = new svec<Command*>; }
+	| staff_commands_body staff_command	{
+		$$->add($2);
 	}
 	;
 
+staff_command:
+	skipcommand
+	| KEY '$' pitch_list '$'	{/*UGH*/
+		$$ = get_key_interpret_command(*$3);
+		delete $3;
+	}
+	| CLEF clef_id			{
+		$$ = get_clef_interpret_command(*$2);
+		delete $2;
+	}
+	;
+
+skipcommand:
+	SKIP int ':' REAL		{
+		$$ = get_skip_command($2, $4);
+	}
+
+score_command:
+	skipcommand
+	| METER  int int		{
+		$$ = get_meterchange_command($2, $3);
+	}
+	| PARTIAL REAL			{
+		$$ = get_partial_command($2);
+	}
+	;
+	
+
+/*
+	PAPER
+*/
 paper_block:
 	PAPER '{' paper_body '}' 	{ $$ = $3; }
 	;
@@ -125,20 +193,8 @@ paper_body:
 	| paper_body UNITSPACE dim	{ $$->whole_width = $3; }
 	| paper_body GEOMETRIC REAL	{ $$->geometric_ = $3; }
 	;
-
-dim:
-	REAL unit	{ $$ = convert_dimen($1,$2); }
-	;
-
-
-unit:	CM		{ $$ = "cm"; }
-	|IN		{ $$ = "in"; }
-	|MM		{ $$ = "mm"; }
-	|PT		{ $$ = "pt"; }
-	;
-	
 /*
-	staff
+	STAFFs
 */
 staff_block:
 	staffdecl
@@ -155,7 +211,13 @@ rhythmstaff_block:
 
 rhythmstaff_body:
 	/* empty */			{ $$ = get_new_rhythmstaff(); }
-	| rhythmstaff_body voice_block 	{ $$->add_voice($2); } 	
+	| rhythmstaff_body voices	{ $$->add(*$2);
+		delete $2;
+	}
+	| rhythmstaff_body staff_commands_block {
+		$$->add(*$2);
+		delete $2;
+	}
 	;
 
 melodicstaff_block:
@@ -164,41 +226,73 @@ melodicstaff_block:
 
 melodicstaff_body:
 	/* empty */			{ $$ = get_new_melodicstaff(); }
-	| melodicstaff_body voice_block 	{ $$->add_voice($2); } 	
+	| melodicstaff_body voices	{
+		$$->add(*$2);
+		delete $2;
+	}	
+	| melodicstaff_body staff_commands_block {
+		$$->input_commands_.add(get_reset_command());
+		$$->add(*$2);
+		delete $2;
+	} 	
 	;
 
-/*
-	voice
-*/
-voice_block:
-	VOICE '{' voice_body '}'	{ $$ = $3; }
+voices:
+	'$' music_voice_body '$'  {
+		$$ = new Voice_list($2->convert());
+	}
+	| VOICES '{' IDENTIFIER '}' 	{
+		$$ = new Voice_list(*$3->voices());
+	}
+	;
+
+
+horizontal_music:
+	music_voice	{ $$ = $1; }
 	;
 
+vertical_music:
+	music_chord	{ $$ = $1; }
+	;
 
-voice_body:
-	IDENTIFIER		{ $$ = new Voice(*$1->voice()); }
-	| voice_elts_dollar	{ $$ = $1; }
-	| voice_body START_T REAL { $$->start = $3; }
+music_voice: VOICE '{' music_voice_body '}'	{ $$ = $3; }
 	;
 
+music_voice_body:			{
+		$$ = new Music_voice;
+	}
+	| music_voice_body full_element {
+		$$->add($2);
+	}
+	| music_voice_body voice_command {
+	}
+	| music_voice_body vertical_music	{
+		$$->add($2);
+	}
+	;
 
-	
 
-voice_elts_dollar:
-	'$' voice_elts '$'  { $$ = $2; }
- 	;
+music_chord: CHORD '{' music_chord_body '}'	{ $$ = $3; }
+	;
+
+music_chord_body:		{
+		$$ = new Music_general_chord;
+	}
+	| music_chord_body horizontal_music {
+		$$ -> add($2);
+	}
+	;
 
-voice_elts:
-	/* empty */		{
-            $$ = new Voice;
-        }
-        | voice_elts pre_requests voice_elt post_requests {
-		add_requests($3, pre_reqs);
-		add_requests($3, post_reqs);
-		$$->add($3);
-        }
 
-	| voice_elts voice_command { }
+
+/*
+	VOICE ELEMENTS
+*/
+full_element:	pre_requests voice_elt post_requests {
+		add_requests($2, pre_reqs);
+		add_requests($2, post_reqs);
+		$$ = $2;
+	}
 	;
 
 post_requests:
@@ -223,16 +317,15 @@ pre_requests:
 pre_request: 
 	OPEN_REQUEST_PARENS		{ $$ = get_request($1); }
 	;
-/*
-*/
+
 voice_command:
-	DURATIONCOMMAND DURATION	{
-		set_default_duration(*$2);
-		delete $2;
+	DURATIONCOMMAND '{' DURATION '}'	{
+		set_default_duration(*$3);
+		delete $3;
 	}
-	| OCTAVECOMMAND PITCH	{
-		set_default_pitch(*$2);
-		delete $2;
+	| OCTAVECOMMAND '{' PITCH '}'	{
+		set_default_pitch(*$3);
+		delete $3;
 	}
 	;
 
@@ -254,7 +347,9 @@ voice_elt:
 		delete $1;
 	}
 	;
-
+/*
+	UTILITIES
+*/
 pitch_list:			{
 		$$ = new svec<String>;
 	}
@@ -263,30 +358,6 @@ pitch_list:			{
 		delete $2;		
 	}
 
-score_command:
-	SKIP int ':' REAL		{
-		$$ = get_skip_command($2, $4);
-	}
-	| METER  int int		{
-		$$ = get_meterchange_command($2, $3);
-	}
-	| KEY '$' pitch_list '$'	{/*UGH*/
-		$$ = get_key_interpret_command(*$3);
-		delete $3;
-	}
-	| CLEF clef_id			{
-		$$ = get_clef_interpret_command(*$2);
-		delete $2;
-	}
-/*	| PARTIALMEASURE REAL		{
-		$$ = get_partial_command($2);
-	}*/
-	;
-	
-clef_id:
-	VIOLIN		{ $$ = new String("violin"); }
-	| BASS		{ $$ = new String("bass"); }
-	;
 int:
 	REAL			{
 		$$ = int($1);
@@ -296,18 +367,37 @@ int:
 	}
 	;
 
+
+dim:
+	REAL unit	{ $$ = convert_dimen($1,$2); }
+	;
+
+
+unit:	CM		{ $$ = "cm"; }
+	|IN		{ $$ = "in"; }
+	|MM		{ $$ = "mm"; }
+	|PT		{ $$ = "pt"; }
+	;
+	
+clef_id:
+	VIOLIN		{ $$ = new String("violin"); }
+	| BASS		{ $$ = new String("bass"); }
+	;
 %%
 
 void
 parse_file(String s)
 {
    *mlog << "Parsing ... ";
+
 #ifdef YYDEBUG
-   yydebug = !monitor.silence("Parser");
+   yydebug = !monitor.silence("Parser") & check_debug;
 #endif
+
    new_input(s);
    yyparse();
    delete_identifiers();
    kill_lexer();
    *mlog << "\n";
 }
+
diff --git a/src/pscore.cc b/src/pscore.cc
index ba1113aa1a..c12f6ddce6 100644
--- a/src/pscore.cc
+++ b/src/pscore.cc
@@ -215,6 +215,8 @@ PScore::postprocess()
     for (PCursor<Item*> ic(its); ic.ok(); ic++){
 	ic->postprocess();
     }
+    for (PCursor<Line_of_score*> i(lines); i.ok(); i++)
+	i->process();
 }
 
 PCursor<PCol *>
diff --git a/src/pstaff.cc b/src/pstaff.cc
index 255fceeadd..ba7789c91b 100644
--- a/src/pstaff.cc
+++ b/src/pstaff.cc
@@ -1,4 +1,9 @@
 #include "pstaff.hh"
+#include "molecule.hh"
+PStaff::~PStaff()
+{
+    delete stafsym;
+}
 
 PStaff::PStaff(PScore*ps)
 {
diff --git a/src/rhythmstaff.cc b/src/rhythmstaff.cc
index c9a7831c1b..6c986a62cc 100644
--- a/src/rhythmstaff.cc
+++ b/src/rhythmstaff.cc
@@ -1,4 +1,6 @@
 #include "molecule.hh"
+#include "score.hh"
+#include "request.hh"
 #include "notehead.hh"
 #include "stem.hh"
 #include "linestaff.hh"
@@ -17,7 +19,8 @@ Rhythmic_staff::set_output(PScore*ps)
 Item *
 Rhythmic_staff::get_TYPESET_item(Command *com)
 {
-    if (com->args[0] == "KEY" || com->args[0] == "CLEF")
+    if (com->args[0] == "KEY" || com->args[0] == "CLEF"||
+	com->args[0] == "CURRENTCLEF")
 	return 0;
     Item *i = Simple_staff::get_TYPESET_item(com);
     if (!i) return 0;
diff --git a/src/scommands.cc b/src/scommands.cc
deleted file mode 100644
index 2787873adb..0000000000
--- a/src/scommands.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-#include "scommands.hh"
-#include "debug.hh"
-#include "parseconstruct.hh"
-
-/*
-  ARG!
-  */
-
-/*
-  maybe it's time for a "narrowing" cursor?
-  */
-PCursor<Command*>
-Score_commands::first(Real w)
-{
-    PCursor<Command*> pc(*this);    
-    while (pc.ok() && pc->when < w)
-	pc++;
-    if (!pc.ok() || pc->when != w) {
-	Command *c = new Command(w);
-	c->priority = 10000;
-	if (!pc.ok())
-	    pc.add(c);
-	else
-	    pc.insert(c);
-    }
-
-    return pc;
-}
-/*
-  RETURN: pc->when == w && pc.ok
- */
-
-PCursor<Command*>
-Score_commands::last_insertion(Real w)
-{    
-    PCursor<Command*> pc(first(w)), next(pc);    
-    while (next.ok() && next->when == w) {
-	pc=next;
-	next++;
-    }
-    if (pc->priority != -10000) {
-	Command*c = new Command(w);
-	c->priority = -10000;
-	pc.add(c);
-	pc++;
-    }
-        
-    return pc;
-}
-
-/*
- */
-void
-Score_commands::add_seq(svec<Command> com, bool checkbreak)
-{
-    if (!com.sz())
-	return;
-    
-    Real when = com[0].when;
-
-    PCursor<Command*> begin(first(when));
-    PCursor<Command*> end(last_insertion(when));
-    if (checkbreak && is_breakable(when)) {
-	if (com[0].priority < 0)
-	    while (begin->code != BREAK_END)
-		begin++;
-	else
-	    while (end->code != BREAK_PRE)
-		end--;
-    }
-    for (int i = 0; i < com.sz(); i++) {
-	insert_between(com[i], begin, end);
-    }
-}
-
-void
-Score_commands::set_breakable(Real when)
-{
-    bool found_typeset(false);
-    PCursor<Command*> cc = first(when);
-    for (; cc.ok() && cc->when == when; cc++) {
-	if (cc->isbreak())
-	    return;
-	if (cc->code == TYPESET)
-	    found_typeset=true;
-    }
-
-    assert(!found_typeset);
-    
-    svec<Command> seq;
-    Command k(when);
-    k.priority = 5;
-    k.code = BREAK_PRE;
-    seq.add(k);
-    k.priority = 4;
-    k.code = BREAK_MIDDLE;
-    seq.add(k);
-    k.priority = 3;
-    k.code = BREAK_POST;
-    seq.add(k);
-    k.priority = 2;
-    k.code = BREAK_END;
-    seq.add(k);
-
-    add_seq(seq,false);
-}
-
-bool
-Score_commands::is_breakable(Real w)
-{
-    PCursor<Command*> cc = first(w);
-    for (; cc.ok() && cc->when == w; cc++) {
-	if (cc->isbreak())
-	    return true;
-    }
-    return false;
-}
-
-void
-Score_commands::insert_between(Command victim, PCursor<Command*> firstc,
-			       PCursor<Command*> last)
-{
-    PCursor<Command*> c(firstc+1);
-    assert(last->when==firstc->when&&firstc < last&&last.ok());
-    
-    while (c < last) { 
-	if (c->priority <= victim.priority) {
-	    c.insert(new Command(victim));
-	    return;
-	}
-	c++;
-    }
-    last.insert(new Command(victim));    
-}
-
-void
-Score_commands::add_command_to_break(Command pre, Command mid, Command post)
-{
-    Real w = pre.when;
-    assert(w >= 0);
-    PCursor<Command*> c ( first(w)), f(c), l(c);
-
-    while (!c->isbreak())
-	c++;
-    f = c++;
-    while (!c->isbreak())
-	c++;
-    l = c++;
-    
-    insert_between(pre, f, l);
-    f = l;
-    while (!c->isbreak())
-	c++;
-    l = c++;    
-    insert_between(mid, f, l);
-    f = l;
-    while (!c->isbreak())
-	c++;
-    l = c++;
-    assert(l.ok() && l->when ==w && l->code == BREAK_END);
-    
-    insert_between(post, f, l);
-}
-
-void
-Score_commands::parser_add(Command *c)
-{
-    bottom().add(c);
-}
-
-void
-Score_commands::process_add(Command c)
-{
-    bool encapsulate =false;
-    Real w = c.when;
-    assert(w >= 0);
-
-    Command pre(w);
-    Command mid(w);
-    Command post(w);
-
-    if (c.code == INTERPRET)
-    {				// UGH
-	if (c.args[0] == "BAR") {
-	    Command typeset(w);	// kut met peren
-	    typeset.code = TYPESET;
-	    typeset.args = c.args;
-	    typeset.priority = 100;
-	    process_add(typeset);
-	} else if (c.args[0] == "KEY") {
-	    Command typeset(w);
-	    typeset.code = TYPESET;
-	    typeset.args.add("KEY");
-	    typeset.priority = 70;
-	    process_add(typeset);
-	} else if (c.args[0] == "CLEF") {
-	    Command typeset(w);
-	    typeset.code = TYPESET;
-	    typeset.args=c.args;
-	    typeset.priority = 90;
-	    process_add(typeset);
-	}
-    }
-
-    // kut en peer
-    if (c.code == TYPESET) {
-	if (c.args[0] == "BAR") {
-	    set_breakable(w);
-	    encapsulate  = true;
-	    mid = c;
-	    pre = c;
-	    { /* every line a currentkey. */
-		Command kc(w);
-		kc.code =TYPESET;
-		kc.args.add( "CURRENTKEY");
-		kc.priority = 60;
-		process_add(kc);
-	    }
-	    { /* every line a currentclef. */
-		Command kc(w);
-		kc.code =TYPESET;
-		kc.args.add( "CURRENTCLEF");
-		kc.priority = 80;
-		process_add(kc);
-	    }
-	}else
-	if (c.args[0] == "METER" && is_breakable(w)) {
-	    encapsulate = true;
-	    mid = c;
-	    pre = c;
-	    post =c;
-	}else
-	if( c.args[0] == "KEY" && is_breakable(c.when)) {
-	    encapsulate = true;
-	    mid = c;
-	    pre = c;
-	    post = c;
-	}else
-	if (c.args[0] == "CURRENTKEY" && is_breakable(w)) {
-	    post = c;
-	    encapsulate = true;
-	}else
-	if (c.args[0] == "CURRENTCLEF" && is_breakable(w)) {
-	    post = c;
-	    encapsulate = true;
-	}else
-	if (c.args[0] == "CLEF" && is_breakable(w)) {
-	    encapsulate = true;
-	    post = c;
-	    pre = c;
-	    mid = c;		       
-	}
-    }
-    
-    if (encapsulate)
-	add_command_to_break(pre, mid, post);    
-    else {
-	svec<Command> seq;
-	seq.add(c);    
-	add_seq(seq,true);
-    }
-}
-
-/*
-    first and last column should be breakable.
-    Remove any command past the last musical column.
-    */
-void
-Score_commands::clean(Real l)
-{
-    assert(l>0);
-    if (!is_breakable(0.0)) {
-	Command c(0.0);
-	c.code = TYPESET;
-	c.args.add("BAR");
-	c.args.add("empty");
-	process_add(c);
-    }
-    
-    PCursor<Command*> bot(bottom());
-
-    while (bot.ok() && bot->when > l) {
-	mtor <<"removing ";
-	bot->print();
-	bot.del();
-	bot = bottom();
-    }
-
-    if (!is_breakable(l)) {
-	Command c(l);
-	c.code = TYPESET;
-	c.args.add("BAR");
-	c.args.add("||");
-	process_add(c);
-    }
-    OK();
-}
-
-void
-Score_commands::OK() const
-{
-    for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
-	assert(cc->when <= (cc+1)->when);
-	if (cc->when == (cc+1)->when && !cc->isbreak() && !(cc+1)->isbreak())
-	    assert(cc->priority >= (cc+1)->priority);
-    }
-}
-
-void
-Score_commands::print() const
-{
-    for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
-	cc->print();
-    }
-}
-
-/*
-  TODO
-  */
-Score_commands*
-Score_commands::parse(Real l) const
-{
-    Score_commands*nc = new Score_commands;
-    int beats_per_meas=4;
-    Real measlen = 1.0; // 4/4 by default
-    
-    Real inbar=0.0;
-    int barcount=0;
-    Real wholes=0.0;
-    Real stoppos=0.0;
-
-    {   /* all pieces should start with a breakable. */
-	Command c(0.0);
-	c.code = INTERPRET;
-	c.args.add("BAR");
-	c.args.add("empty");
-	nc->process_add(c);
-    }
-    for (PCursor<Command*> cc(*this); cc.ok() && cc->when <= l; cc++) {
-	assert (cc->code==INTERPRET);
-	if (cc->args[0] == "METER") {
-	    beats_per_meas = cc->args[1].value();
-	    int one_beat = cc->args[2].value();
-	    measlen = beats_per_meas/Real(one_beat);
-	    nc->process_add(*get_meter_command(wholes, beats_per_meas, one_beat));
-	}
-	if (cc->args[0] == "KEY"||cc->args[0] == "CLEF") {
-	    cc->when = wholes;
-	    nc->process_add(**cc);
-	}
-	if (cc->args[0] == "SKIP") {
-	    stoppos = wholes + cc->args[1].value() * measlen +
-		cc->args[2].fvalue();
-	    wholes += (measlen-inbar); // skip at least 1 measure
-	    barcount++;
-	    while (wholes <= stoppos) {
-		nc->process_add(*get_bar_command(wholes)); // liek
-		wholes += measlen;
-		barcount ++;		
-	    }
-	    wholes = stoppos;
-	    //something
-	}
-    }
-    
-    return nc;
-}
diff --git a/src/score.cc b/src/score.cc
index f421baaae6..60ab3931f9 100644
--- a/src/score.cc
+++ b/src/score.cc
@@ -1,5 +1,7 @@
-#include "scommands.hh"
+#include "staffcommands.hh"
 #include "tstream.hh"
+#include "getcommand.hh"
+#include "inputcommands.hh"
 #include "score.hh"
 #include "sccol.hh"
 #include "pscore.hh"
@@ -7,38 +9,14 @@
 #include "debug.hh"
 #include "paper.hh"
 
-void
-Score::set(Paperdef*p)
-{
-    delete paper_;
-    paper_ = p;
-}
-
-void
-Score::output(String s)
-{
-    OK();
-    if (paper_->outfile=="")
-	paper_->outfile = s;
-    
-    *mlog << "output to " << paper_->outfile << "...\n";
-    Tex_stream the_output(paper_->outfile);    
-    pscore_->output(the_output);
-}
-
-
 void
 Score::process()
 {
     *mlog << "Processing ... ";
-    set(commands_->parse(last()));
-    commands_->print();
     
     if (!paper_)
 	paper_ = new Paperdef;
     
-    commands_->clean(last());
-    
     /// distribute commands to disciples
     distribute_commands();
     
@@ -51,23 +29,23 @@ Score::process()
     // do this after processing, staffs first have to generate PCols.
     do_pcols();
     calc_idealspacing();
-    clean_cols();
+    clean_cols();		// ugh. Would want to clean the columns before anything else.
+
+
     OK();
-    //    print();
 
     pscore_->preprocess();
     *mlog << "Calculating ... ";
     pscore_->calc_breaking();
+    *mlog << "Postprocessing ... ";
     pscore_->postprocess();
 
-    // TODO: calculate vertical structs
-    // TODO: calculate mixed structs.
+    // TODO: calculate vertical structs?
+    // TODO: calculate mixed structs.?
     *mlog << "\n";
 }
 
-// remove empty cols with no spacing attached.
-/* should rethink ownership of cols
-    */
+// remove empty cols.
 void
 Score::clean_cols()
 {    
@@ -85,9 +63,10 @@ Score::clean_cols()
     
     pscore_->clean_cols();
 }
-/* this sux.  We should have Score_column create the appropriate PCol.
-    Unfortunately, PCols don't know about their position.    
-    */
+/*
+  this sux.  We should have Score_column create the appropriate PCol.
+  Unfortunately, PCols don't know about their position.    
+  */
 // todo
 PCursor<Score_column*>
 Score::create_cols(Real w)
@@ -119,7 +98,7 @@ Score::create_cols(Real w)
     return scc;
 }
 
-Score_column*
+PCursor<Score_column*>
 Score::find_col(Real w,bool mus)
 {
     PCursor<Score_column*> scc(cols_);
@@ -136,10 +115,10 @@ Score::find_col(Real w,bool mus)
 }
 
 void
-Score::distribute_commands(void)
+Score::distribute_commands()
 {
     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-	sc->add_commands(*commands_);
+	sc->process_input_commands(input_commands_, last());
     }
 }
 void
@@ -181,7 +160,6 @@ Score::OK() const
     for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
 	assert(cc->when <= (cc+1)->when);
     }
-    commands_->OK();
 #endif    
 }
 
@@ -197,7 +175,6 @@ Score::print() const
     for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
 	sc->print();
     }
-    commands_->print();
     mtor << "}\n";
 #endif
 }
@@ -206,19 +183,39 @@ Score::Score()
 {
     pscore_=0;
     paper_ = 0;
-    commands_ = new Score_commands;
 }
 
 Score::~Score()
 {
     delete pscore_;
-    delete commands_;
+    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
+Score::output(String s)
+{
+    OK();
+    if (paper_->outfile=="")
+	paper_->outfile = s;
+    
+    *mlog << "output to " << paper_->outfile << "...\n";
+    Tex_stream the_output(paper_->outfile);    
+    pscore_->output(the_output);
+}
+
 
 void
-Score::set(Score_commands*c)
+Score::add(svec<Command*> &s)
 {
-    delete commands_;
-    commands_ = c;
+    input_commands_.add(get_reset_command());
+    input_commands_.concat(s);
 }
+
diff --git a/src/scoreline.cc b/src/scoreline.cc
index 03d0c8482f..bd21c32bba 100644
--- a/src/scoreline.cc
+++ b/src/scoreline.cc
@@ -41,3 +41,11 @@ Line_of_score::Line_of_score(svec<const PCol *> sv,
     #sv# isn't really const!!
     */
 
+
+void
+Line_of_score::process()
+{
+    for (PCursor<Line_of_staff*> i(staffs); i.ok(); i++)
+	i->process();
+}
+	
diff --git a/src/simpleprint.cc b/src/simpleprint.cc
index eb8c80759c..3a0ac3dde3 100644
--- a/src/simpleprint.cc
+++ b/src/simpleprint.cc
@@ -20,8 +20,10 @@ Simple_staff::get_TYPESET_item(Command *com)
 	s = new Bar(com->args[1]);	
     } else if (type == "METER") {
 	s = new Meter(arg);
-    } else if (type == "CLEF") {
-	s = new Clef_item;
+    } else if (type == "CLEF" ||type == "CURRENTCLEF") {
+	Clef_item * c = new Clef_item;
+	s = c;
+	c->change = (type == "CLEF");	
     }else{
 	WARN << "ignoring TYPESET command for " << type << '\n';
 
diff --git a/src/simplestaff.cc b/src/simplestaff.cc
index 1afe0eed08..6437b65c3a 100644
--- a/src/simplestaff.cc
+++ b/src/simplestaff.cc
@@ -1,4 +1,5 @@
 #include "request.hh"
+#include "voice.hh"
 #include "swalker.hh"
 #include "debug.hh"
 #include "clef.hh"
diff --git a/src/simplewalker.cc b/src/simplewalker.cc
index 4918b5e6fa..7705e045a9 100644
--- a/src/simplewalker.cc
+++ b/src/simplewalker.cc
@@ -1,4 +1,5 @@
 #include "request.hh"
+#include "voice.hh"
 #include "clef.hh"
 #include "beam.hh"
 #include "pscore.hh"
@@ -35,7 +36,7 @@ Simple_walker::do_INTERPRET_command(Command*com)
 	s.del(0);
 	clef_.read(s);
     } else {
-	WARN << " ignoring INTERPRET command: " << com->args[0];
+	WARN << " ignoring INTERPRET command: " << com->args[0]<< '\n';
     }
 }
 
@@ -50,11 +51,10 @@ Simple_walker::do_TYPESET_command(Command*com)
 	else
 	    com->args[0] = "KEY"; 
     
-    if (com->args[0] == "CURRENTCLEF")
-	if (processed_clef) {	    
+    if (com->args[0] == "CURRENTCLEF") {
+	if (processed_clef) 
 	    return;
-	} else
-	    com->args[0] = "CLEF";
+    }
     
 
     Item* i = staff()->get_TYPESET_item(com);
@@ -71,9 +71,11 @@ Simple_walker::do_TYPESET_command(Command*com)
 	((Keyitem*) i)->read(typesetkey); // ugh	
     }
 
-    if (com->args[0] == "CLEF") {
+    if (com->args[0] == "CLEF"||com->args[0] == "CURRENTCLEF") {
 	processed_clef =true;
-	((Clef_item*)i)->read(clef_);	
+	Clef_item*c=(Clef_item*)i;
+	c->read(clef_);
+	c->change = (break_status != BREAK_POST - BREAK_PRE);
     }
     col()->typeset_item_directional(i, 1, break_status);
 }
@@ -84,6 +86,7 @@ Simple_walker::do_local_key(Note_req*n)
     if ( local_key_.oct(n->octave).acc(n->name) != n->accidental) {
 	if (!local_key_item_) {
 	    local_key_item_ = staff()->get_local_key_item();
+	    local_key_item_->c0_position = clef_.c0_pos;
 	}
 	
 	local_key_item_->add(n->octave, n->name, n->accidental);	
@@ -125,7 +128,8 @@ Simple_walker::process_requests()
     Simple_staff *s = staff();
     if (c->beam_&& c->beam_->spantype == Span_req::START) {
 	if (beam_)
-	    error("Too many beams");
+	    error("Too many beams (t = "
+			  +String(c->when())+")");
 	beam_ = new Beam;
     }
     for (int i=0; i < c->slurs.sz(); i++) {
@@ -148,13 +152,17 @@ Simple_walker::process_requests()
     }
     
     if (beam_) {
+	if (!stem_)
+	    error("beamed note should have a stem (t = " 
+		  +String(c->when())+")");
 	beam_->add(stem_);
     }
     if (stem_) {
 	c->typeset_item(stem_);
 	/* needed, otherwise placement of
 	   local_key fucks up */
-	stem_->set_default_extents();
+//	stem_->set_default_extents();
+	// can somebody explain myself?
     }
     if (c->beam_&& c->beam_->spantype == Span_req::STOP) {
 	pscore_->typeset_spanner(beam_, s->theline);
diff --git a/src/staff.cc b/src/staff.cc
index 4b3322fcef..9b65539de5 100644
--- a/src/staff.cc
+++ b/src/staff.cc
@@ -1,21 +1,57 @@
 #include "staff.hh"
+#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);
-    PL_copy(commands,src.commands);
+    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)
+{
+    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();
+}
+
 Paperdef*
-Staff::paper() const{
+Staff::paper() const
+{
     return score_->paper_;
 }
 
@@ -60,7 +96,8 @@ Staff::get_col(Real w, bool mus)
 //  ;  assert((i-1).ok())
     // todo!
     
-    // making a fix at 2:30 am, with several beers drunk. 
+    // making a fix at 2:30 am, with several beers drunk.
+    // but it works :-)
     if ((i-1).ok()&& (i-1)->when() == newst->when()) {
 	i--;
     }
@@ -82,10 +119,8 @@ 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++) {
 
@@ -95,38 +130,12 @@ Staff::setup_staffcols()
 	}	
     }
 
-    for (PCursor<Command*> cc(commands); cc.ok(); cc++) {
+    for (PCursor<Command*> cc(*staff_commands_); cc.ok(); cc++) {
 	Staff_column *sc=get_col(cc->when,false);
 	sc->s_commands.add(cc);
     }
 }
 
-/// merge commands from score
-void
-Staff::add_commands(PointerList<Command*> const &cl)
-{
-    PCursor<Command*> score_c(cl);
-    PCursor<Command*> cc(commands);
-    
-    while (score_c.ok()) {
-	while (cc.ok() && cc->when <= score_c->when)
-	    cc++;
-	
-	Command*nc = new Command (*(* score_c));
-	if (cc.ok()) {
-	    // cc->when > score_c->when
-	    cc.insert( nc );
-	} else {
-	    commands.bottom().add( nc);
-	    cc = commands.bottom();
-	}
-	score_c++;
-    }
-
-    // now integrate break commands with other commands.
-    // maybe do this in derived functions.
-}
-
 void
 Staff::process()
 {
@@ -140,7 +149,6 @@ Staff::OK() const
 {
 #ifndef NDEBUG
     cols.OK();
-    commands.OK();
     voices.OK();
     assert(score_);    
 #endif    
@@ -164,15 +172,19 @@ Staff::print() const
 #ifndef NPRINT
     mtor << "Staff {\n";
     for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
-	vc->print();
-	
+	vc->print();	
     }
+    if (staff_commands_)
+	staff_commands_->print();
+    for (int i =0; i <input_commands_.sz(); i++)
+	input_commands_[i]->print();
     mtor <<"}\n";
 #endif
 }
 
 Staff::Staff()
 {
+    staff_commands_ = 0;
     score_ =0;
     pscore_=0;    
 }
diff --git a/src/staffcommands.cc b/src/staffcommands.cc
new file mode 100644
index 0000000000..96647b1de6
--- /dev/null
+++ b/src/staffcommands.cc
@@ -0,0 +1,318 @@
+#include "staffcommands.hh"
+#include "debug.hh"
+#include "parseconstruct.hh"
+
+/*
+  ARG!
+  */
+
+/*
+  maybe it's time for a "narrowing" cursor?
+  */
+PCursor<Command*>
+Staff_commands::first(Real w)
+{
+    PCursor<Command*> pc(*this);    
+    while (pc.ok() && pc->when < w)
+	pc++;
+    if (!pc.ok() || pc->when != w) {
+	Command *c = new Command(w);
+	c->priority = 10000;
+	if (!pc.ok())
+	    pc.add(c);
+	else
+	    pc.insert(c);
+    }
+
+    return pc;
+}
+/*
+  RETURN: pc->when == w && pc.ok
+ */
+
+PCursor<Command*>
+Staff_commands::last_insertion(Real w)
+{    
+    PCursor<Command*> pc(first(w)), next(pc);    
+    while (next.ok() && next->when == w) {
+	pc=next;
+	next++;
+    }
+    if (pc->priority != -10000) {
+	Command*c = new Command(w);
+	c->priority = -10000;
+	pc.add(c);
+	pc++;
+    }
+        
+    return pc;
+}
+
+/*
+ */
+void
+Staff_commands::add_seq(svec<Command> com, bool checkbreak)
+{
+    if (!com.sz())
+	return;
+    
+    Real when = com[0].when;
+
+    PCursor<Command*> begin(first(when));
+    PCursor<Command*> end(last_insertion(when));
+    if (checkbreak && is_breakable(when)) {
+	if (com[0].priority < 0)
+	    while (begin->code != BREAK_END)
+		begin++;
+	else
+	    while (end->code != BREAK_PRE)
+		end--;
+    }
+    for (int i = 0; i < com.sz(); i++) {
+	insert_between(com[i], begin, end);
+    }
+}
+
+void
+Staff_commands::set_breakable(Real when)
+{
+    bool found_typeset(false);
+    PCursor<Command*> cc = first(when);
+    for (; cc.ok() && cc->when == when; cc++) {
+	if (cc->isbreak())
+	    return;
+	if (cc->code == TYPESET)
+	    found_typeset=true;
+    }
+
+    assert(!found_typeset);
+    
+    svec<Command> seq;
+    Command k(when);
+    k.priority = 5;
+    k.code = BREAK_PRE;
+    seq.add(k);
+    k.priority = 4;
+    k.code = BREAK_MIDDLE;
+    seq.add(k);
+    k.priority = 3;
+    k.code = BREAK_POST;
+    seq.add(k);
+    k.priority = 2;
+    k.code = BREAK_END;
+    seq.add(k);
+
+    add_seq(seq,false);
+}
+
+bool
+Staff_commands::is_breakable(Real w)
+{
+    PCursor<Command*> cc = first(w);
+    for (; cc.ok() && cc->when == w; cc++) {
+	if (cc->isbreak())
+	    return true;
+    }
+    return false;
+}
+
+void
+Staff_commands::insert_between(Command victim, PCursor<Command*> firstc,
+			       PCursor<Command*> last)
+{
+    PCursor<Command*> c(firstc+1);
+    assert(last->when==firstc->when&&firstc < last&&last.ok());
+    
+    while (c < last) { 
+	if (c->priority <= victim.priority) {
+	    c.insert(new Command(victim));
+	    return;
+	}
+	c++;
+    }
+    last.insert(new Command(victim));    
+}
+
+void
+Staff_commands::add_command_to_break(Command pre, Command mid, Command post)
+{
+    Real w = pre.when;
+    assert(w >= 0);
+    PCursor<Command*> c ( first(w)), f(c), l(c);
+
+    while (!c->isbreak())
+	c++;
+    f = c++;
+    while (!c->isbreak())
+	c++;
+    l = c++;
+    
+    insert_between(pre, f, l);
+    f = l;
+    while (!c->isbreak())
+	c++;
+    l = c++;    
+    insert_between(mid, f, l);
+    f = l;
+    while (!c->isbreak())
+	c++;
+    l = c++;
+    assert(l.ok() && l->when ==w && l->code == BREAK_END);
+    
+    insert_between(post, f, l);
+}
+
+void
+Staff_commands::process_add(Command c)
+{
+    bool encapsulate =false;
+    Real w = c.when;
+    assert(w >= 0);
+
+    Command pre(w);
+    Command mid(w);
+    Command post(w);
+
+    if (c.code == INTERPRET)
+    {				// UGH
+	if (c.args[0] == "BAR") {
+	    Command typeset(w);	// kut met peren
+	    typeset.code = TYPESET;
+	    typeset.args = c.args;
+	    typeset.priority = 100;
+	    process_add(typeset);
+	} else if (c.args[0] == "KEY") {
+	    Command typeset(w);
+	    typeset.code = TYPESET;
+	    typeset.args.add("KEY");
+	    typeset.priority = 70;
+	    process_add(typeset);
+	} else if (c.args[0] == "CLEF") {
+	    Command typeset(w);
+	    typeset.code = TYPESET;
+	    typeset.args=c.args;
+	    typeset.priority = 90;
+	    process_add(typeset);
+	} else if (c.args[0] == "METER") {
+	    Command typeset(w);
+	    typeset.code = TYPESET;
+	    typeset.args=c.args;
+	    typeset.priority = 40;
+	    process_add(typeset);
+	    return;
+	}
+    }
+
+    // kut en peer
+    if (c.code == TYPESET) {
+	if (c.args[0] == "BAR") {
+	    set_breakable(w);
+	    encapsulate  = true;
+	    mid = c;
+	    pre = c;
+	    { /* every line a currentkey. */
+		Command kc(w);
+		kc.code =TYPESET;
+		kc.args.add( "CURRENTKEY");
+		kc.priority = 60;
+		process_add(kc);
+	    }
+	    { /* every line a currentclef. */
+		Command kc(w);
+		kc.code =TYPESET;
+		kc.args.add( "CURRENTCLEF");
+		kc.priority = 80;
+		process_add(kc);
+	    }
+	}else
+	if (c.args[0] == "METER" && is_breakable(w)) {
+	    encapsulate = true;
+	    mid = c;
+	    pre = c;
+	    post =c;
+	}else
+	if( c.args[0] == "KEY" && is_breakable(c.when)) {
+	    encapsulate = true;
+	    mid = c;
+	    pre = c;
+	    post = c;
+	}else
+	if (c.args[0] == "CURRENTKEY" && is_breakable(w)) {
+	    post = c;
+	    encapsulate = true;
+	}else
+	if (c.args[0] == "CURRENTCLEF" && is_breakable(w)) {
+	    post = c;
+	    encapsulate = true;
+	}else
+	if (c.args[0] == "CLEF" && is_breakable(w)) {
+	    encapsulate = true;
+	    post = c;
+	    pre = c;
+	    mid = c;		       
+	}
+    }
+    
+    if (encapsulate)
+	add_command_to_break(pre, mid, post);    
+    else {
+	svec<Command> seq;
+	seq.add(c);    
+	add_seq(seq,true);
+    }
+}
+
+/*
+    first and last column should be breakable.
+    Remove any command past the last musical column.
+    */
+void
+Staff_commands::clean(Real l)
+{
+    assert(l>0);
+    if (!is_breakable(0.0)) {
+	Command c(0.0);
+	c.code = TYPESET;
+	c.args.add("BAR");
+	c.args.add("empty");
+	process_add(c);
+    }
+    
+    PCursor<Command*> bot(bottom());
+
+    while (bot.ok() && bot->when > l) {
+	mtor <<"removing ";
+	bot->print();
+	bot.del();
+	bot = bottom();
+    }
+
+    if (!is_breakable(l)) {
+	Command c(l);
+	c.code = TYPESET;
+	c.args.add("BAR");
+	c.args.add("||");
+	process_add(c);
+    }
+    OK();
+}
+
+void
+Staff_commands::OK() const
+{
+    for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
+	assert(cc->when <= (cc+1)->when);
+	if (cc->when == (cc+1)->when && !cc->isbreak() && !(cc+1)->isbreak())
+	    assert(cc->priority >= (cc+1)->priority);
+    }
+}
+
+void
+Staff_commands::print() const
+{
+#ifndef NPRINT
+    for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
+	cc->print();
+    }
+#endif
+}
diff --git a/src/staffline.cc b/src/staffline.cc
index f0f00f1a83..a51c669e1f 100644
--- a/src/staffline.cc
+++ b/src/staffline.cc
@@ -4,6 +4,7 @@
 #include "spanner.hh"
 #include "symbol.hh"
 #include "paper.hh"
+#include "molecule.hh"
 #include "pcol.hh"
 #include "pscore.hh"
 
@@ -24,10 +25,11 @@ Line_of_staff::TeXstring() const
     s+=make_vbox(height());
     // the staff itself: eg lines, accolades
     s += "\\hbox{";
-    {
-	Symbol sym = pstaff_->get_stafsym(line_of_score_->pscore_-> // ugh
-					  paper_->linewidth);
-	s+=sym.tex;
+    {				
+	((PStaff*)pstaff_)->
+	    brew_molecule(line_of_score_->pscore_->paper_->linewidth);
+
+	s+=pstaff_->stafsym->TeXstring();
 	PCursor<const PCol *> cc(line_of_score_->cols);
 	Real lastpos=cc->hpos;
 
@@ -82,9 +84,7 @@ Line_of_staff::height() const
 {
     Interval y;
     {
-	Symbol s = pstaff_->stafsym->eval(line_of_score_->pscore_->
-					  paper_->linewidth);
-	y = s.dim.y;
+	y = pstaff_->stafsym->extent().y;
     }
     PCursor<const PCol *> cc(line_of_score_->cols);
     
@@ -105,4 +105,10 @@ Line_of_staff::height() const
     return y;
 }
 
-
+void
+Line_of_staff::process()
+{
+    if (!pstaff_->stafsym)
+	pstaff_->brew_molecule(line_of_score_->pscore_->
+			       paper_->linewidth);
+}
diff --git a/src/stem.cc b/src/stem.cc
index 126cc30474..8ba21e82c6 100644
--- a/src/stem.cc
+++ b/src/stem.cc
@@ -104,7 +104,8 @@ Stem::set_default_extents()
 void
 Stem::postprocess()
 {
-    set_default_extents();
+    if (bot == top)
+	set_default_extents();
     brew_molecole();
 }
 
diff --git a/src/symbol.cc b/src/symbol.cc
index 02723e19b0..ce9507f8b8 100644
--- a/src/symbol.cc
+++ b/src/symbol.cc
@@ -13,22 +13,4 @@ Symbol::Symbol(String s, Box b)
     tex = s;
 }
 
-/****************************************************************/
-
-Symbol
-Parametric_symbol::eval(String args1)const
-{
-    svec<String> a;
-    a.add(args1);
-    return eval(a);
-}
-
-Symbol
-Parametric_symbol::eval(String args1,String arg2)const
-{
-    svec<String> a;
-    a.add(args1);
-    a.add(arg2);
-    return eval(a);
-}
 
diff --git a/src/table.cc b/src/table.cc
index f2407904a1..7a54241f9f 100644
--- a/src/table.cc
+++ b/src/table.cc
@@ -6,32 +6,37 @@
 #include "associter.hh"
 #include "parser.hh"
 
-static Keyword_ent  the_key_tab[]={
-    "voice", VOICE,
-    "rhythmstaff", RHYTHMSTAFF,
-    "melodicstaff", MELODICSTAFF,
-    "clef", CLEF,
-    "score", SCORE,
+static Keyword_ent the_key_tab[]={
     "bar", BAR,
-    "output", OUTPUT,
+    "bass", BASS,
+    "clef", CLEF,
     "cm", CM,
-    "start", START_T,
-    "pt", PT,
+    "commands", COMMANDS,
+    "duration", DURATIONCOMMAND,
+    "geometric", GEOMETRIC,
     "in", IN,
+    "key", KEY, 
+    "melodicstaff", MELODICSTAFF,
+    "meter", METER,
     "mm", MM,
+    "octave", OCTAVECOMMAND,
+    "output", OUTPUT,
+    "partial", PARTIAL,
     "paper", PAPER,
-    "width", WIDTH,
-    "violin", VIOLIN,
-    "bass", BASS,
-    "meter", METER,
-    "unitspace", UNITSPACE,
+    "pt", PT,
+    "rhythmstaff", RHYTHMSTAFF,
+    "score", SCORE,
     "skip", SKIP,
-    "octave", OCTAVECOMMAND,
-    "commands", COMMANDS,
     "staff", STAFF,
-    "geometric", GEOMETRIC,
-    "duration", DURATIONCOMMAND,
-    "key", KEY, 
+    "start", START_T,
+    "table", TABLE,
+    "chord", CHORD,
+    "multi", MULTI,
+    "unitspace", UNITSPACE,
+    "violin", VIOLIN,
+    "voice", VOICE,
+    "voices", VOICES,
+    "width", WIDTH,   
     0,0
 } ;
 
diff --git a/src/template2.cc b/src/template2.cc
index 23e6aae200..d2d42f954f 100644
--- a/src/template2.cc
+++ b/src/template2.cc
@@ -1,7 +1,7 @@
 
 #include "symbol.hh"
 #include "voice.hh"
-
+#include "request.hh"
 #include "staff.hh"
 #include "sccol.hh"
 #include "stcol.hh"
diff --git a/src/template3.cc b/src/template3.cc
index a457b6afbb..80921422fa 100644
--- a/src/template3.cc
+++ b/src/template3.cc
@@ -1,4 +1,3 @@
-#include "request.hh"
 #include "command.hh"
 #include "molecule.hh"
 #include "plist.cc"
@@ -6,5 +5,5 @@
 
 IPL_instantiate(Atom);
 IPL_instantiate(Command);
-IPL_instantiate(Request);
+
 
diff --git a/src/texbeam.cc b/src/texbeam.cc
index e21efba0be..01545405c6 100644
--- a/src/texbeam.cc
+++ b/src/texbeam.cc
@@ -39,7 +39,7 @@ slope_index(Real &s)
     if (s>0)
 	return 6*i +122;
     else
-	return -6 * i+ 188;
+	return -6 * i+ 186;
 }
 
 Symbol
diff --git a/src/texslur.cc b/src/texslur.cc
index 413c21869d..e3966daaa6 100644
--- a/src/texslur.cc
+++ b/src/texslur.cc
@@ -140,7 +140,7 @@ Lookup::slur (int dy , Real &dx, int dir)
 	if (dx >= convert_dimen(4*54, "pt"))
 	    error("slur too wide");
 	idx = widx;
-	if (dir > 0)
+	if (dir < 0)
 	    idx += 54;		
     }
     
@@ -158,7 +158,6 @@ Symbol
 Lookup::big_slur(int dy , Real &dx, int dir)
 {
     assert(dx >= convert_dimen(24,"pt"));
-
     Real slur_extra =ABS(dy)  /2.0 + 2; 
     int l_dy = Real (dy)/2 + slur_extra*dir;
     int r_dy =  dy - l_dy;
@@ -169,6 +168,7 @@ Lookup::big_slur(int dy , Real &dx, int dir)
     Atom l = half_slur(l_dy, left_wid, dir, -1);
     Atom r = half_slur(r_dy, right_wid, dir, 1);
     Real mid_wid = dx - left_wid - right_wid;
+
     Atom m = half_slur(0, mid_wid, dir, 0);
 
     Molecule mol;
@@ -177,7 +177,7 @@ Lookup::big_slur(int dy , Real &dx, int dir)
     a.translate(Offset(0,slur_extra * internote()));
     mol.add_right(m);
     mol.add_right(r);
-    mol.translate(Offset(l_dy * internote(), 0));
+    mol.translate(Offset(0, l_dy * internote()));
     Symbol s;
     s.tex = mol.TeXstring();
     s.dim = mol.extent();
diff --git a/src/voice.cc b/src/voice.cc
index fbdb207aab..8a1c136d04 100644
--- a/src/voice.cc
+++ b/src/voice.cc
@@ -1,5 +1,6 @@
 #include "debug.hh"
 #include "voice.hh"
+#include "request.hh"
 
 Voice::Voice(Voice const&src)
 {
@@ -74,5 +75,5 @@ Voice_element::Voice_element(Voice_element const&src)
     voice_=src.voice_;
     IPointerList__copy(Request*, reqs, src.reqs, clone());
     group=src.group;
-    assert(!granted_items.size() && !granted_spanners.size());
+//    assert(!granted_items.size() && !granted_spanners.size());
 }
diff --git a/src/warn.cc b/src/warn.cc
index 6d35d8cad6..230e4bb976 100644
--- a/src/warn.cc
+++ b/src/warn.cc
@@ -1,6 +1,8 @@
 #include "debug.hh"
- ostream &warnout (cerr);
- ostream *mlog(&cerr);
+#include "lexer.hh"
+
+ostream &warnout (cerr);
+ostream *mlog(&cerr);
 
 
 
@@ -14,7 +16,19 @@ warning(String s)
 void
 error(String s)
 {
-    cerr << "\nerror: " << s << "\n";
+    if (busy_parsing())
+	yyerror(s);
+    else
+	cerr <<  "\nerror: " << s << "\n";
+	
+    exit(1);
+}
+
+void
+error_t(String s, Real r)
+{
+    String e=s+ "(t = " + r + ")";
+    error(e);
     exit(1);
 }
 
diff --git a/symbol.ini b/symbol.ini
index 4dc2753347..5b1d6e303e 100644
--- a/symbol.ini
+++ b/symbol.ini
@@ -11,6 +11,9 @@ table clefs
 	violin	\violinclef 0pt	16pt	-12.5pt	22.5pt
 	bass 	\bassclef 0pt	16pt	0pt	20pt
 	viola	\violaclef 0pt	16pt	0pt	20pt
+	violin_change	\cviolinclef 0pt	16pt	-12.5pt	22.5pt
+	bass_change 	\cbassclef 0pt	16pt	0pt	20pt
+	viola_change	\cviolaclef 0pt	16pt	0pt	20pt
 end
 
 table balls
@@ -38,7 +41,7 @@ end
 
 table bars
 	empty	\emptybar	0pt	0pt	0pt	0pt
-	|	\maatstreep	0pt	1pt 	-12pt	12pt
+	|	\maatstreep	0pt	5pt 	-12pt	12pt
 	||	\finishbar	0pt	2pt	-12pt	12pt
 end