From f3b8153dec5313fd5d539fc5aca9c7699de152ee Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Fri, 15 Nov 1996 11:08:37 +0100
Subject: [PATCH] release: 0.0.6

---
 .dstreamrc        |   5 +-
 CodingStyle       |  55 ++++++++++++++++
 Makefile          |  13 ++--
 README            |  51 +++++++++++++-
 Sources.make      |  18 +++--
 TODO              |   4 +-
 break.cc          |   4 +-
 debug.hh          |  17 +++--
 flower/Makefile   |   2 +-
 flower/TODO       |   2 +
 flower/list.hh    |   2 +-
 flower/matrix.cc  |   2 -
 flower/pcursor.hh |   2 +-
 flower/string.hh  |   1 +
 flower/vector.cc  |   5 +-
 flower/vray.hh    |   5 ++
 identifier.cc     |  19 +++---
 identifier.hh     |  32 +++++++++
 keyword.hh        |   9 ---
 lexer.hh          |   3 +-
 lexer.l           |  18 +++--
 lilyponddefs.tex  |  66 ++++++++++++-------
 line.cc           |   5 +-
 line.hh           |   2 +-
 linespace.hh      |   2 +-
 linestaff.cc      |   7 +-
 linestaff.hh      |   5 +-
 lookupsyms.cc     |  46 ++++++++-----
 lookupsyms.hh     |  19 ++++--
 maartje.ly        |  23 ++++---
 melodicstaff.cc   |  54 +++++++++++++++
 melodicstaff.hh   |  31 +++++++++
 misc.cc           |   5 +-
 molecule.hh       |   2 +-
 note.cc           |  16 +++--
 paper.cc          |  53 ++++++++++++++-
 paper.hh          |  19 ++++--
 parseconstruct.hh |   2 +-
 parser.y          |  51 ++++++++++++--
 pcol.hh           |   2 +-
 proto.hh          |   6 +-
 pscore.cc         |  11 ++--
 pscore.hh         |   5 +-
 pstaff.cc         |   3 +-
 pstaff.hh         |  12 ++--
 qlp.cc            |   2 +-
 request.cc        |  31 +++++++++
 request.hh        |  25 ++++---
 rhythmstaf.cc     | 165 ----------------------------------------------
 rhythmstaf.hh     |  48 --------------
 rhythmstaff.cc    |  52 +++++++++++++++
 rhythmstaff.hh    |  35 ++++++++++
 scommands.hh      |   2 +-
 score.cc          |   5 +-
 score.hh          |   2 +-
 simpleprint.cc    |  79 ++++++++++++++++++++++
 simplestaff.cc    |  86 ++++++++++++++++++++++++
 simplestaff.hh    |  59 +++++++++++++++++
 staff.cc          |  27 ++++++--
 staff.hh          |   9 +--
 stcol.hh          |   2 +
 symbol.cc         |   3 -
 symbol.hh         |   7 +-
 symbol.ini        |  25 ++++---
 symtable.cc       |  14 +---
 symtable.hh       |   7 +-
 table.cc          |  11 +++-
 template1.cc      |   4 +-
 template2.cc      |   1 +
 template3.cc      |   1 +
 voice.hh          |   7 +-
 71 files changed, 992 insertions(+), 433 deletions(-)
 create mode 100644 CodingStyle
 create mode 100644 identifier.hh
 create mode 100644 melodicstaff.cc
 create mode 100644 melodicstaff.hh
 delete mode 100644 rhythmstaf.cc
 delete mode 100644 rhythmstaf.hh
 create mode 100644 rhythmstaff.cc
 create mode 100644 rhythmstaff.hh
 create mode 100644 simpleprint.cc
 create mode 100644 simplestaff.cc
 create mode 100644 simplestaff.hh

diff --git a/.dstreamrc b/.dstreamrc
index fccd8d5c37..7dcded772c 100644
--- a/.dstreamrc
+++ b/.dstreamrc
@@ -15,4 +15,7 @@ parse_duration		1
 parse_pitch		1
 Col_configuration	1
 Command			1
-Score_commands		1
\ No newline at end of file
+Score_commands		1
+Note_req		1
+Rhythmic_req		1
+Rest_req		1
\ No newline at end of file
diff --git a/CodingStyle b/CodingStyle
new file mode 100644
index 0000000000..c5d730c0a6
--- /dev/null
+++ b/CodingStyle
@@ -0,0 +1,55 @@
+CODING STANDARDS:
+
+Functions and methods do not return errorcodes, but use assert for
+checking status. 
+
+INDENTATION, in emacs:
+
+
+(add-hook 'c-mode-hook
+	  '(lambda ()(setq c-basic-offset 4)))
+
+
+(add-hook 'c++-mode-hook
+	  '(lambda() (c-set-style "Stroustrup")
+	     )
+	  )
+
+
+CLASSES and TYPES:
+
+	This_is_a_class
+
+DATA MEMBERS
+
+	Class:member
+
+if the member's name resembles its type, then we use
+
+	Class Fubular { ..}
+
+	Class::fubular_
+
+COMMENTS
+
+/// short description
+class Class {
+	///
+	Data data_member_;
+	/**
+		..
+	*/
+
+	/****************/
+
+	/// short memo
+	member();
+	/**
+		long doco of member()
+	*/
+};
+/**
+	Class documentation.
+*/
+
+Unfortunately most of the code isn't really documented that good.
\ No newline at end of file
diff --git a/Makefile b/Makefile
index c1636f4012..c85f6fd2ff 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 MAJVER=0
 MINVER=0
-PATCHLEVEL=5
+PATCHLEVEL=6
 
 # 
 #
@@ -20,16 +20,19 @@ PACKAGENAME=lilypond
 DNAME=$(PACKAGENAME)-$(VERSION)
 othersrc=lexer.l parser.y
 SCRIPTS=make_version make_patch genheader
-IFILES=dimen.tex symbol.ini suzan.ly maartje.ly  lilyponddefs.tex test.tex .dstreamrc
+IFILES=dimen.tex symbol.ini suzan.ly maartje.ly\
+	lilyponddefs.tex test.tex .dstreamrc
 OFILES=Makefile Sources.make 
-DOC=COPYING README TODO
+DOC=COPYING README TODO CodingStyle
 DFILES=$(hdr) $(mycc) $(othersrc) $(OFILES) $(IFILES) $(SCRIPTS) $(DOC)
 
 #compiling
 LOADLIBES=-L$(FLOWERDIR) -lflower
 FLOWERDIR=../flower
-#DEFINES=-DNDEBUG -DNPRINT -O2 			# speedy
-DEFINES=-g					# lots of debugging info
+# speedy
+#DEFINES=-DNDEBUG -DNPRINT -O2
+# lots of debugging info
+DEFINES=-g
 
 CXXFLAGS=$(DEFINES) -I$(FLOWERDIR) -pipe -Wall -W  -pedantic 
 FLEX=flex
diff --git a/README b/README
index 0ad234c7ff..b60e7f2bbd 100644
--- a/README
+++ b/README
@@ -1,4 +1,6 @@
+-*-text-*-
 
+INTRODUCTION
 
 This is a beta version of LilyPond (a music typesetter). This release is
 preliminary, please do not distribute. Please send your helpful comments and
@@ -6,6 +8,51 @@ patches to me,
 
   hanwen@stack.urc.tue.nl
 
-If you actually want to use this, you'd better use the "speed"
-compilation flags in the Makefile
+PREREQUISITES
 
+TeX, the MusixTeX fonts, g++ > v2.7. The "flower" library, which should be
+available from the same source you got this from.
+
+COMPILING
+
+You will need GNU C++ v2.7 or better and GNU make.  If you actually
+want to use this, you'd better use the "speedy" compilation flags in
+the Makefile.
+
+USING
+
+No, you shouldn't. Really. If you're still not discouraged; this is
+what I type in my xterm:
+
+	lilypond maartje.ly
+	tex test
+	xdvi test&
+
+This is what the output looks like over here.
+
+hw:~/musix/spacer$ lilypond maartje.ly
+LilyPond version 0.0.6 compiled on Nov  2 1996 at 01:25:29
+Parsing ... [maartje.ly]
+output to lelie.uit...
+hw:~/musix/spacer$ tex test
+This is TeX, Version 3.14159 (C version 6.1)
+(test.tex
+Hyphenation patterns for english, dutch, loaded.
+(lilyponddefs.tex) (lelie.uit) [1] )
+Output written on test.dvi (1 page, 1964 bytes).
+Transcript written on test.log.
+hw:~/musix/spacer$ xdvi test&
+[1] 3130
+hw:~/musix/spacer$ 
+
+
+PROBLEMS
+
+If LilyPond bombs out, then please recompile using -g, and send a gdb
+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.
diff --git a/Sources.make b/Sources.make
index 6c420edad7..deb1a524c4 100644
--- a/Sources.make
+++ b/Sources.make
@@ -1,17 +1,20 @@
-hdr=    qlp.hh       \
-	linespace.hh   qlpsolve.hh\
-	pcol.hh   proto.hh pstaff.hh  line.hh\
+# -*- Makefile-*-
+# sourcefiles to be shipped. Also for depedencies
+
+hdr=    qlp.hh linespace.hh qlpsolve.hh\
+	pcol.hh proto.hh pstaff.hh  line.hh\
 	const.hh glob.hh molecule.hh  boxes.hh pscore.hh item.hh tex.hh\
 	request.hh voice.hh command.hh staff.hh  linestaff.hh \
-	tstream.hh   rhythmstaf.hh\
+	tstream.hh rhythmstaff.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 lookupsyms.hh\
-	sccol.hh stcol.hh scommands.hh
+	sccol.hh stcol.hh scommands.hh melodicstaff.hh\
+	identifier.hh simplestaff.hh
 
 mycc=   qlp.cc qlpsolve.cc \
 	break.cc linespace.cc molecule.cc line.cc\
-	pscore.cc tex.cc item.cc pcol.cc staff.cc rhythmstaf.cc\
+	pscore.cc tex.cc item.cc pcol.cc staff.cc rhythmstaff.cc\
 	score.cc note.cc  main.cc misc.cc \
 	symbol.cc request.cc notename.cc  voice.cc\
 	keyword.cc linestaff.cc table.cc command.cc\
@@ -19,5 +22,6 @@ mycc=   qlp.cc qlpsolve.cc \
 	pstaff.cc  tstream.cc version.cc\
 	calcideal.cc scores.cc identifier.cc \
 	dimen.cc paper.cc lookupsyms.cc scommands.cc\
-	sccol.cc stcol.cc getcommands.cc\
+	sccol.cc stcol.cc getcommands.cc simplestaff.cc\
+	melodicstaff.cc simpleprint.cc\
 	template1.cc template2.cc template3.cc
diff --git a/TODO b/TODO
index cce684e09c..d60c09dbb7 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,6 @@
-melodie staff.
+fonttables -> fontdims
+clear IDENTIFIERs
+Paperdef -> fontsize .
 beam + stem
 
 
diff --git a/break.cc b/break.cc
index b8dc1827bc..7d5a02a10e 100644
--- a/break.cc
+++ b/break.cc
@@ -2,7 +2,7 @@
     do calculations for breaking problem
     
     */
-
+#include "paper.hh"
 #include "linespace.hh"
 #include "debug.hh"
 #include "line.hh"
@@ -17,7 +17,7 @@ PScore::solve_line(svec<const PCol *> curline) const
    sp.add_column(curline[0], true, 0.0);
    for (int i=1; i< curline.sz()-1; i++)
        sp.add_column(curline[i]);
-   sp.add_column(curline.last(), true, linewidth);
+   sp.add_column(curline.last(), true, paper_->linewidth);
 
    // misschien  moeven uit Spacing_problem? 
    for (PCursor<Idealspacing *> i(suz); i.ok(); i++) {
diff --git a/debug.hh b/debug.hh
index 200585608b..fb3a070593 100644
--- a/debug.hh
+++ b/debug.hh
@@ -4,20 +4,25 @@
 #include <iostream.h>
 #include "dstream.hh"
 
+void error(String s);		// errors
 
-
+// warnings
+void warning(String s);
 #define WARN warnout << "warning: "<<__FUNCTION__ << "(): "
 extern ostream &warnout ;
-extern ostream *mlog;  
-extern ostream *nulldev;  
+
+// progress
+extern ostream *mlog;
+
+// debugging
 extern Dstream monitor; // monitor
 
 #ifdef NPRINT
-#define mtor *nulldev
+#define mtor if (0) monitor	// clever hack 
 #else
 #define mtor monitor.identify_as(__PRETTY_FUNCTION__)
 #endif
-void error(String s);
-void warning(String s);
+
+
 
 #endif
diff --git a/flower/Makefile b/flower/Makefile
index 5b40b40629..3e9a70ce15 100644
--- a/flower/Makefile
+++ b/flower/Makefile
@@ -1,6 +1,6 @@
 MAJVER=1
 MINVER=0
-PATCHLEVEL=5
+PATCHLEVEL=6
 
 PACKAGENAME=flower
 VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL)
diff --git a/flower/TODO b/flower/TODO
index bcb4e27042..f7070ecd07 100644
--- a/flower/TODO
+++ b/flower/TODO
@@ -1,5 +1,7 @@
 	* PointerList<T>:List<T> -> PointerList<T>:List<T*>
 
+	* PCursor -> Pointer_cursor / PointerCursor ?
+
 	* efficient copy cons for List
 
 	* change String::pos
diff --git a/flower/list.hh b/flower/list.hh
index 6edf4aebc4..5a825fa89e 100644
--- a/flower/list.hh
+++ b/flower/list.hh
@@ -11,9 +11,9 @@ template<class T> class Link;
 template<class T>
 class List
 {
+ public:
     List(List const&src);
 
- public:
     /// construct empty list                
     List();
     
diff --git a/flower/matrix.cc b/flower/matrix.cc
index 1afe5951c8..b95a4ab1f9 100644
--- a/flower/matrix.cc
+++ b/flower/matrix.cc
@@ -1,6 +1,4 @@
 #include "matrix.hh"
-#include "string.hh"
-
 
 Real
 Matrix::norm() const
diff --git a/flower/pcursor.hh b/flower/pcursor.hh
index eb0e8f15f9..095bcc45bf 100644
--- a/flower/pcursor.hh
+++ b/flower/pcursor.hh
@@ -25,7 +25,7 @@ struct PCursor : public Cursor<T> {
     PCursor(const List<T> & l) : Cursor<T> (l) {}
 
     PCursor( const Cursor<T>& cursor ) : Cursor<T>(cursor) { }
-    T operator ->() { return  *(*this); }
+    T operator ->() const { return  *(*(Cursor<T> *)this); }
 
 };
 /**
diff --git a/flower/string.hh b/flower/string.hh
index d3d2774261..77912beda2 100644
--- a/flower/string.hh
+++ b/flower/string.hh
@@ -50,6 +50,7 @@ public:
     char *copy_array() const; //  return a "new"-ed copy of contents
 
     const char *ptr() const;
+    const char *ptr() { return ((const String *)this)->ptr(); }
     /// return the data. Don't use for writing the data.
     operator const char *() const { return ptr(); }
     
diff --git a/flower/vector.cc b/flower/vector.cc
index 2cbfdfc899..bb3008ee5e 100644
--- a/flower/vector.cc
+++ b/flower/vector.cc
@@ -1,5 +1,4 @@
 #include "vector.hh"
-#include "string.hh"
 
 Vector::Vector(const Vector&n)
           :dat(n.dat)
@@ -9,7 +8,9 @@ Vector::Vector(const Vector&n)
 Vector
 Vector::operator-() const
 {
-    Vector v(*this); v*=-1; return v;
+    Vector v(*this);
+    v*=-1;
+    return v;
 }
 
 void
diff --git a/flower/vray.hh b/flower/vray.hh
index d56cad00d6..c03e651034 100644
--- a/flower/vray.hh
+++ b/flower/vray.hh
@@ -141,6 +141,11 @@ public:
 	sort(compare, lower, last-1);
 	sort(compare, last+1, lower);
     }
+    void concat(svec<T> const &src) {
+	int s = size;
+	set_size(size + src.size);
+	arrcpy(thearray+s,src.thearray, src.size);	
+    }
 };
 /**
 
diff --git a/identifier.cc b/identifier.cc
index 9eab42e114..94d48c8d74 100644
--- a/identifier.cc
+++ b/identifier.cc
@@ -1,22 +1,21 @@
 #include <assert.h>
-#include "keyword.hh"
+#include "identifier.hh"
+#include "staff.hh"
 #include "lexer.hh"
 #include "parser.hh"
 
-Identifier::Identifier()
+Identifier::Identifier(String n)
+    :name  (n)
 {
     data = 0;
-    type = IDENTIFIER;
 }
 
 
 Identifier::~Identifier()
 {
-    if (!data)
-	return;
-    switch (type) {
-    case IDENTIFIER:
-    default:
-	assert(false);
-    }
+}
+
+Staff_id::~Staff_id()
+{
+    delete staff();
 }
diff --git a/identifier.hh b/identifier.hh
new file mode 100644
index 0000000000..0510f181d1
--- /dev/null
+++ b/identifier.hh
@@ -0,0 +1,32 @@
+
+/*
+  identifier.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef IDENTIFIER_HH
+#define IDENTIFIER_HH
+#include "proto.hh"
+#include "string.hh"
+
+struct Identifier
+{
+    void *data;
+    String name;
+    
+    Identifier(String n) ;
+    virtual ~Identifier();
+    virtual Staff * staff() { assert(false); }
+};
+
+struct Staff_id : Identifier {
+    Staff_id(String s, Staff*st):Identifier(s) { data = st; }
+    virtual Staff* staff() { return (Staff*) data; }
+    ~Staff_id();
+};
+
+
+
+#endif // IDENTIFIER_HH
+
diff --git a/keyword.hh b/keyword.hh
index 42267ef57a..df4547ad76 100644
--- a/keyword.hh
+++ b/keyword.hh
@@ -12,12 +12,3 @@ struct Keyword_table
     Keyword_table(Keyword_ent *);
     int     lookup(const char *s) const;
 };
-
-struct Identifier
-{
-    void *data;
-    int type;
-
-    Identifier();
-    ~Identifier();
-};
diff --git a/lexer.hh b/lexer.hh
index 28753603ef..31be74169f 100644
--- a/lexer.hh
+++ b/lexer.hh
@@ -9,6 +9,7 @@ int yylex();
 void yyerror(char *s);
 
 int lookup_keyword(String s);
-Identifier* lookup_identifier(String s);
 
+Identifier* lookup_identifier(String s);
+void add_identifier(Identifier*i);
 #endif
diff --git a/lexer.l b/lexer.l
index 46a30cf752..008f813bf5 100644
--- a/lexer.l
+++ b/lexer.l
@@ -92,11 +92,17 @@ REAL		[0-9]+(\.[0-9]*)?
 }
 {WORD}		{
 	int l = lookup_keyword(YYText());
-	if (l == -1){
-            yylval.id = lookup_identifier(YYText());
-	    return IDENTIFIER;
-        } else
-            return l;
+	if (l != -1)
+		return l;
+	Identifier * id = lookup_identifier(YYText());
+	if (id) {		
+		yylval.id = id;
+		return IDENTIFIER;
+	}
+	String *sp = new String( YYText());
+	mtor << "new id: " << *sp;
+	yylval.string=sp;
+	return NEWIDENTIFIER;
 }
 
 {REAL}		{
@@ -113,7 +119,7 @@ REAL		[0-9]+(\.[0-9]*)?
 	mtor << "parens\n";
 	return YYText()[0];
 }
-[:]		{
+[:=]		{
 	char c = YYText()[0];
 	mtor << "misc char" <<c<<"\n";
 	return c;
diff --git a/lilyponddefs.tex b/lilyponddefs.tex
index 9b18faf880..24dd617150 100644
--- a/lilyponddefs.tex
+++ b/lilyponddefs.tex
@@ -1,41 +1,53 @@
+%%
+%% include file for LilyPond
+\def\mdef#1#2{\def#1{{\musicfnt\char#2}}}
+
+%% musix defs
+	\parindent=0pt
+	\newdimen\interlinedist
+	\newcount\n
+	\newdimen\balkhoog
+	\newdimen\staffrulethickness
+	\newdimen\interstaffrule
+
 \def\musixtwentydefs{
 	\font\musicfnt=musix20
-
-%	\hulplijnbreedte5pt
-	%\hlijnhoogte1pt
-	%\balkskip4pt
+	\interlinedist=5pt
+	\balkhoog=20pt
+	\staffrulethickness=0.4pt
+	\interstaffrule=\balkhoog
+	\advance\interstaffrule by-\staffrulethickness
+	\divide\interstaffrule by 4
+	\advance\interstaffrule by -\staffrulethickness		
 }
+
 \def\interstaffline{
 	\vskip 20pt%
 }
 
 \musixtwentydefs
-\def\mdef#1#2{\def#1{{\musicfnt\char#2}}}
+
 \mdef\quartball{'007}
 \mdef\halfball{'010}
 \mdef\wholeball{'011}
-\mdef\wholerest{'075}
 \mdef\halfrest{'074}
-\mdef\quartrest{'076}
-\mdef\eighthrest{'077}
-\mdef\sixteenthrest{'078}
-\mdef\thirtysecondrest{'079}
+\mdef\wholerest{'075}
+\mdef\quartrest{62}
+\mdef\eighthrest{63}
+\mdef\sixteenthrest{64}
+\mdef\thirtysecondrest{65}
 \mdef\sharp{'065}
 \mdef\flat{'063}
 \mdef\natural{'067}
 \mdef\singledot{'00}
 \mdef\doubledot{'01}
 \mdef\tripledot{'02}
+\mdef\mussepline{155}
 
+\def\maatstreep{\vrule height\balkhoog}
+\def\finishbar{\vrule height\balkhoog  width 1pt}
+\def\generalmeter#1#2{\vbox to 0pt{\vss\rm\hbox{#1}\hbox{#2}}}
 
-
-\def\maatstreep{\vrule height8pt depth8pt }
-\def\finishbar{\vrule height8pt width 1pt depth8pt}
-\parindent0pt
-
-\def\generalmeter#1#2{\vbox to 0pt{\vss\rm\hbox{#1}\hbox{#2}\vss}}
-
-\mdef\mussepline{155}
 \def\lineseparator{\vbox{\mussepline\vskip -5pt\mussepline}}
 \def\interscoreline{
 	\par\vskip 10pt\par
@@ -43,10 +55,18 @@
 	\vskip 10pt
 }
 
-\newcount\n
-\def\linestafsym#1#2{\hbox to 0pt{\vbox to 0pt{\n=0%
+%
+% a staffsymbol with #1 lines, width #2
+% bottom at baseline
+\def\linestafsym#1#2{\hbox to 0pt%
+  {\vbox to 0pt{\vss%
+	\vskip-\interlinedist
+	\n=0%
 	\loop\ifnum\n<#1\advance\n by1%
-	\ifnum\n>1\vskip2pt\fi \hrule width#2\repeat\vss}\hss}}
+		\vskip\interstaffrule \hrule height \staffrulethickness	width#2
+		\repeat
+	}%
+\hss}}
 
 \def\vcenter#1{\vbox to 0pt{\vss #1\vss}}
 
@@ -57,4 +77,6 @@
 
 \def\lsingledot{\kern-6pt\singledot}
 \def\ldoubledot{\kern-6pt\doubledot}
-\def\ltripledot{\kern-6pt\tripledot}
\ No newline at end of file
+\def\ltripledot{\kern-6pt\tripledot}
+
+
diff --git a/line.cc b/line.cc
index ebe9595d3b..a6e0f7c68a 100644
--- a/line.cc
+++ b/line.cc
@@ -1,6 +1,7 @@
 #include "line.hh"
 #include "dimen.hh"
 #include "symbol.hh"
+#include "paper.hh"
 #include "pcol.hh"
 #include "pscore.hh"
 
@@ -16,7 +17,7 @@ Line_of_staff::TeXstring() const
     // the staff itself: eg lines, accolades
     s += "\\hbox{";
     {
-	Symbol sym = pstaff_->get_stafsym(scor->score->linewidth);
+	Symbol sym = pstaff_->get_stafsym(scor->score->paper_->linewidth);
 	s+=sym.tex;
 	PCursor<const PCol *> cc(scor->cols);
 	Real lastpos=cc->hpos;
@@ -105,7 +106,7 @@ Line_of_staff::maxheight() const
 {
     Interval y;
     {
-	Symbol s = pstaff_->stafsym->eval(scor->score->linewidth);
+	Symbol s = pstaff_->stafsym->eval(scor->score->paper_->linewidth);
 	y = s.dim.y;
     }
     PCursor<const PCol *> cc(scor->cols);
diff --git a/line.hh b/line.hh
index ec45bd577c..3e698659e9 100644
--- a/line.hh
+++ b/line.hh
@@ -6,7 +6,7 @@
 */
 
 #include "real.hh"
-#include "list.hh"
+#include "plist.hh"
 #include "vray.hh"
 #include "glob.hh"
 #include "pstaff.hh"
diff --git a/linespace.hh b/linespace.hh
index e5b23ca7f0..b9d850c602 100644
--- a/linespace.hh
+++ b/linespace.hh
@@ -2,7 +2,7 @@
 #define PROBLEM_HH
 
 #include "glob.hh"
-#include "list.hh"
+#include "plist.hh"
 #include "vray.hh"
 #include "pcol.hh"
 #include "matrix.hh"
diff --git a/linestaff.cc b/linestaff.cc
index dd9227b155..7cd081dc49 100644
--- a/linestaff.cc
+++ b/linestaff.cc
@@ -2,11 +2,14 @@
 #include "symbol.hh"
 #include "lookupsyms.hh"
 #include "dimen.hh"
+#include "paper.hh"
+#include "pscore.hh"
 
-Linestaff::Linestaff(int l)
+Linestaff::Linestaff(int l, PScore *s)
+    : PStaff(s)
 {
     nolines = l;
-    stafsym = Lookup::linestaff(l); 
+    stafsym = s->paper_->lookup_->linestaff(l); 
 }
 
 Symbol
diff --git a/linestaff.hh b/linestaff.hh
index 33e9d39f4e..891269dd9d 100644
--- a/linestaff.hh
+++ b/linestaff.hh
@@ -4,7 +4,8 @@ struct Linestaff : PStaff {
     
     int nolines;
 
-    Symbol get_stafsym(Real width)const;
-    Linestaff(int);
+/****************/
     
+    Symbol get_stafsym(Real width)const;
+    Linestaff(int, PScore*);   
 };
diff --git a/lookupsyms.cc b/lookupsyms.cc
index 14b3ab11e3..f0624cad1e 100644
--- a/lookupsyms.cc
+++ b/lookupsyms.cc
@@ -3,35 +3,50 @@
 #include "symtable.hh"
 #include "dimen.hh"
 #include "tex.hh"
+void
+Lookup::parse(Text_db&t)
+{
+    symtables_->read(t) ;
+}
 
-Symtables the_sym_tables("symbol.ini");
+Lookup::Lookup()
+{
+    symtables_ = new Symtables;
+}
+
+Lookup::~Lookup()
+{
+    delete symtables_;
+}
 
 Symbol
 Lookup::ball(int j)
 {
-    if (j > 4) j = 4;
-    Symtable * st = the_sym_tables("balls");
+    if (j > 4)
+	j = 4;
+
+    Symtable * st = (*symtables_)("balls");
     return st->lookup(String(j));
 }
 
 Symbol
 Lookup::rest(int j)
 {
-    return the_sym_tables("rests")->lookup(String(j));
+    return (*symtables_)("rests")->lookup(String(j));
 }
 
 
- Symbol
+Symbol
 Lookup::bar(String s)
 {
-    return the_sym_tables("bars")->lookup(s);
+    return (*symtables_)("bars")->lookup(s);
 }
  Symbol
 Lookup::dots(int j)
 {
     if (j>3)
 	error("max 3 dots");
-    return the_sym_tables("dots")->lookup(j);
+    return (*symtables_)("dots")->lookup(j);
 }
 
 /****************************************************************/
@@ -39,7 +54,7 @@ Lookup::dots(int j)
 
 struct Linestaf_symbol : Parametric_symbol {
     int lines;
-    Linestaf_symbol(int n) { lines = n;}
+    Linestaf_symbol(int n, Symtables*s): Parametric_symbol(s) { lines = n;}
     Symbol eval(svec<String>)const;
 };
 
@@ -51,26 +66,27 @@ Linestaf_symbol::eval(svec<String> w)const
 
     Symbol s;
     s.dim.x = Interval(0,wid);
-    s.dim.y = Interval(0, lines*convert_dimen(5,"pt"));
+    Real dy=lines*convert_dimen(5,"pt");
+    s.dim.y = Interval(0,dy);
     svec<String> a;
     a.add(lines);
     a.add(w[0]);
-    s.tex = the_sym_tables("param")->lookup("linestaf").tex;
+    s.tex = (*symtables_)("param")->lookup("linestaf").tex;
     s.tex = substitute_args(s.tex, a);
     return s;
 }
 
-/****************************************************************
- */
+/****************************************************************/
 
 
 struct Meter_sym:Parametric_symbol {
 
+    Meter_sym(Symtables*s) : Parametric_symbol(s){  }
     Symbol eval(svec<String> a) const{
 	Symbol s;
 	s.dim.x = Interval( convert_dimen(-5,"pt"), convert_dimen(10,"pt"));
 	s.dim.y = Interval(0, convert_dimen(10,"pt") );	// todo
-	String src = the_sym_tables("param")->lookup("meter").tex;
+	String src = (*symtables_)("param")->lookup("meter").tex;
 	s.tex = substitute_args(src,a);
 	return s;
     }
@@ -80,12 +96,12 @@ struct Meter_sym:Parametric_symbol {
 Parametric_symbol *
 Lookup::meter(String )
 {
-    return new Meter_sym;
+    return new Meter_sym(symtables_);
 }
 
 Parametric_symbol *
 Lookup::linestaff(int n)
 {
-    return new Linestaf_symbol(n);
+    return new Linestaf_symbol(n,symtables_);
 }
 
diff --git a/lookupsyms.hh b/lookupsyms.hh
index d4e08667db..a3c0750d0e 100644
--- a/lookupsyms.hh
+++ b/lookupsyms.hh
@@ -7,12 +7,19 @@
 #include "symbol.hh"
 
 struct Lookup {
-    static Parametric_symbol *linestaff(int n);
-    static Parametric_symbol *meter(String);
-    static Symbol ball(int);
-    static Symbol rest(int);
-    static Symbol bar(String);
-    static Symbol dots(int);
+    Symtables *symtables_;
+    
+    /****************/
+
+    void parse (Text_db&t);
+    Parametric_symbol *linestaff(int n);
+    Parametric_symbol *meter(String);
+    Symbol ball(int);
+    Symbol rest(int);
+    Symbol bar(String);
+    Symbol dots(int);
+    Lookup();
+    ~Lookup();
 };
 
 #endif
diff --git a/maartje.ly b/maartje.ly
index 508389a12e..00d4ea8d5e 100644
--- a/maartje.ly
+++ b/maartje.ly
@@ -1,23 +1,26 @@
-% erg lang
 
 
+ritme = rhythmstaff {
+	voice { $ c2 r32 r32 r16 r8 r4 c2 c2 c2 c2 c2
+		c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $ }
+}
+melody=
+melodicstaff {
+  voice { $ c2.. r8 r4 r8 r16 r32 r32 d8 e8 f8 g8 a8 b8 'c8 c8 r4 c4 c4 c4 c4 c4 c4 $ }
+}
 score {
 	paper {
 		unitspace 3 cm
 	}
-	rhythmstaff {
-		voice { $ c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 c2 $ }
-	}
-	rhythmstaff {
-		voice { $ c2.. r8 c4 r4 c4 r4 c4 r4 c4 r4 c4 r4 c4 r4 c4 r4
-		r2 r4 r1
-	$ }
-	}
+	staff { ritme }
+	staff { melody }
 	commands {
 		meter 4 4
 		skip 3:0
 		meter 2 4
-		skip 8:0
+		skip 19:0
 	}
 }
 
+
+
diff --git a/melodicstaff.cc b/melodicstaff.cc
new file mode 100644
index 0000000000..60d9a6fd2e
--- /dev/null
+++ b/melodicstaff.cc
@@ -0,0 +1,54 @@
+#include "melodicstaff.hh"
+#include "paper.hh"
+#include "molecule.hh"
+#include "linestaff.hh"
+#include "rhythmstaff.hh"
+#include "sccol.hh" 
+
+void
+Melodic_staff::set_output(PScore*ps)
+{
+    theline = new Linestaff(5,ps);
+    Simple_staff::set_output(ps);
+}
+
+void
+Melodic_column::typeset_command(Command *com, int breakst)
+{
+    Item *i = create_command_item(com);
+    typeset_item(i, breakst);
+}
+
+void
+Melodic_column::typeset_req(Request *rq)
+{
+    Item *i = create_req_item(rq);
+    if (rq->note()) {
+	int h = rq->note()->height();
+	Real dy = staff_->paper()->interline()/2;
+	i->output->translate(Offset(0,(h-2)*dy));
+    }
+    typeset_item(i);
+}
+
+/*
+  creation
+  */
+Staff *
+get_new_melodicstaff()
+{
+    return new Melodic_staff;
+}
+
+
+Staff_column*
+Melodic_staff::create_col(Score_column*s)
+{
+    return new Melodic_column(s,this);
+}
+
+Melodic_staff*
+Melodic_staff::clone()const
+{
+    return new Melodic_staff(*this);
+}
diff --git a/melodicstaff.hh b/melodicstaff.hh
new file mode 100644
index 0000000000..a91a413659
--- /dev/null
+++ b/melodicstaff.hh
@@ -0,0 +1,31 @@
+/*
+  rhythmstaf.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef MELODICSTAFF_HH
+#define MELODICSTAFF_HH
+
+#include "simplestaff.hh"
+
+/// five line staff, no multiple voices
+struct Melodic_staff : public Simple_staff
+{
+    Staff_column * create_col(Score_column*);
+    virtual void set_output(PScore *);
+    virtual Melodic_staff*clone()const;
+};
+
+struct Melodic_column : public Simple_column {
+    virtual void typeset_req(Request *rq);
+  virtual void typeset_command(Command *, int brs);
+  //    virtual void typeset_item(Item*, int=1);
+    Melodic_column(Score_column*s,Simple_staff*rs) :
+	Simple_column(s,rs) { }
+//    virtual Melodic_column*clone()const;
+};
+
+#endif // MELODICSTAFF_HH
+
+
diff --git a/misc.cc b/misc.cc
index 3a8658f4a0..174e4224bc 100644
--- a/misc.cc
+++ b/misc.cc
@@ -18,10 +18,9 @@ double log2(double x) {
 
 
 // golden ratio
- 
-const Real PHI = (1+sqrt(5))/2;
+ const Real PHI = (1+sqrt(5))/2;
 const double ENGRAVERS_SPACE = PHI;
-const double WHOLE_SPACE = 5.0; // should be settable from input
+
 
 
   
diff --git a/molecule.hh b/molecule.hh
index 05ec64e3e0..0c69f74040 100644
--- a/molecule.hh
+++ b/molecule.hh
@@ -1,7 +1,7 @@
 #ifndef MOLECULE_HH
 #define MOLECULE_HH
 
-#include "list.hh"
+#include "plist.hh"
 #include "boxes.hh"
 #include "item.hh"
 #include "symbol.hh"
diff --git a/note.cc b/note.cc
index 2307729a3c..bb0702f143 100644
--- a/note.cc
+++ b/note.cc
@@ -63,8 +63,6 @@ parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
 	}
 
     
-    mtor << "ov " << overide_acc;
-    
     // notename.
     String nm;
     while (isalpha(a[j])) 
@@ -78,8 +76,9 @@ parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
 	}
         
 
-    lookup_notename(large,small,nm);    
-    mtor << "int "<< large <<" "<<small<<" ";    
+    lookup_notename(large,small,nm);
+    mtor << "override: " << overide_acc;    
+    mtor << "pitch "<< large <<", "<<small<<"\n";    
 }
 
 
@@ -98,13 +97,18 @@ get_note_element(String pitch, String durstr)
     int oct, pit, acc;
     bool forceacc;
     parse_pitch(pitch, i, oct, forceacc, pit, acc);
-
+    char nm =  pit + 'c';
+    if (nm > 'g')
+	nm += 'a' - 'h';
+    rq->name =nm;
+    
     rq->octave = oct;
     rq->accidental = acc;
     rq->forceacc = forceacc;
     rq->balltype = dur;
     rq->dots = dots;
     
+    rq->print();
 
     v->add(rq);
     return v;
@@ -124,7 +128,7 @@ get_rest_element(String, String durstr)
   
     rq->balltype = dur;
     rq->dots = dots;    
-
+    rq->print();
     v->add(rq);
     return v;
 }
diff --git a/paper.cc b/paper.cc
index 5afee7d56f..6e5e87bda8 100644
--- a/paper.cc
+++ b/paper.cc
@@ -1,8 +1,57 @@
 #include "paper.hh"
+#include "debug.hh"
+#include "lookupsyms.hh"
 #include "dimen.hh"
+#include "textdb.hh"
 
 Paperdef::Paperdef()
 {
-    width = convert_dimen(15,"cm");		// in cm for now
-    whole_width= convert_dimen(5,"cm");
+    linewidth = convert_dimen(15,"cm");		// in cm for now
+    whole_width= convert_dimen(2,"cm");
+    lookup_ = new Lookup();
+    parse();
+    
+}
+
+void 
+Paperdef::parse()
+{
+    Text_db symini("symbol.ini");
+
+    
+    while (!symini.eof()) {
+	
+	 Text_record  r(  symini++);
+	
+	 if  (r[0] == "symboltables")
+	     lookup_->parse(symini);	 
+    }
+}
+
+Paperdef::~Paperdef()
+{
+    delete lookup_;
+}
+
+Real
+Paperdef::interline() const
+{
+    return lookup_->ball(4).dim.y.length();
+}
+
+Real
+Paperdef::standard_height() const
+{
+    return convert_dimen(20,"pt");
+}
+
+void
+Paperdef::print() const
+{
+#ifndef NPRINT
+    mtor << "Paper {width: " << print_dimen(linewidth);
+    mtor << "whole: " << print_dimen(whole_width);
+    mtor << "out: " <<outfile;
+    mtor << "}\n";
+#endif
 }
diff --git a/paper.hh b/paper.hh
index b48391a4b9..9ce4d2bf4e 100644
--- a/paper.hh
+++ b/paper.hh
@@ -1,13 +1,20 @@
-
-
+#include "proto.hh"
 #include "real.hh"
 #include "string.hh"
+
 struct Paperdef {
-    Paperdef();
+    Lookup *lookup_;
     String outfile;
-    Real width;
+    Real linewidth;
     /// how much space does a whole note take (ideally?)
     Real whole_width;
-    // maybe add pointsize?
-    // symbol init?
+    
+    /****************/
+    void parse();
+    Paperdef();
+    ~Paperdef();
+    Real interline()const;
+    Real standard_height()const;
+    void print() const;
 };
+
diff --git a/parseconstruct.hh b/parseconstruct.hh
index d2f2c1ac4a..ea5c2fe55a 100644
--- a/parseconstruct.hh
+++ b/parseconstruct.hh
@@ -5,7 +5,7 @@ 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();
 Command* get_meterchange_command( int,int);
 Command* get_meter_command( Real,int,int);
 Command* get_skip_command( int,Real);
diff --git a/parser.y b/parser.y
index ebc4c54f8b..7e2be63a68 100644
--- a/parser.y
+++ b/parser.y
@@ -11,6 +11,7 @@
 #include "debug.hh"
 #include "parseconstruct.hh"
 #include "dimen.hh"
+#include "identifier.hh"
 
 #ifndef NDEBUG
 #define YYDEBUG 1
@@ -36,13 +37,15 @@
 
 %token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
 %token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
+%token MELODICSTAFF
 
 %type <consstr> unit
-%token <id> IDENTIFIER
+%token <id>  IDENTIFIER
+%token <string> NEWIDENTIFIER 
 %token <string> PITCH DURATION RESTNAME
 %token <real> REAL
 %token <string> STRING
-
+%type <id> declaration 
 %type <paper> paper_block paper_body
 %type <real> dim
 %type <voice> voice_block voice_body voice_elts voice_elts_dollar
@@ -50,14 +53,28 @@
 %type <command> score_command
 %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
 
 %%
 
 mudela:	/* empty */
-	| score_block { 
-		add_score($1);
+	| mudela score_block { 
+		add_score($2);
+	}
+	| mudela add_declaration {	}
+	;
+
+add_declaration: declaration	{
+		add_identifier($1);
+	}
+	;
+
+declaration:
+	NEWIDENTIFIER '=' staff_block  {
+		$$ = new Staff_id(*$1, $3);
+		delete $1; // this sux
 	}
 	;
 
@@ -86,7 +103,7 @@ paper_block:
 
 paper_body:
 	/* empty */		 	{ $$ = new Paperdef; }
-	| paper_body WIDTH dim		{ $$->width = $3;}
+	| paper_body WIDTH dim		{ $$->linewidth = $3;}
 	| paper_body OUTPUT STRING	{ $$->outfile = *$3;
 		delete $3;
 	}
@@ -104,9 +121,16 @@ unit:	CM		{ $$ = "cm"; }
 	|PT		{ $$ = "pt"; }
 	;
 	
-
+/*
+	staff
+*/
 staff_block:
-	rhythmstaff_block
+	staffdecl
+	| rhythmstaff_block
+	| melodicstaff_block
+	;
+
+staffdecl: STAFF '{' IDENTIFIER '}' { $$ = $3->staff(); }
 	;
 
 rhythmstaff_block:
@@ -118,6 +142,18 @@ rhythmstaff_body:
 	| rhythmstaff_body voice_block 	{ $$->add_voice($2); } 	
 	;
 
+melodicstaff_block:
+	MELODICSTAFF '{' melodicstaff_body '}'	{ $$ = $3; }
+	;
+
+melodicstaff_body:
+	/* empty */			{ $$ = get_new_melodicstaff(); }
+	| melodicstaff_body voice_block 	{ $$->add_voice($2); } 	
+	;
+
+/*
+	voice
+*/
 voice_block:
 	VOICE '{' voice_body '}'	{ $$ = $3; }
 	;
@@ -183,4 +219,5 @@ parse_file(String s)
 #endif
    new_input(s);
    yyparse();
+   *mlog << "\n";
 }
diff --git a/pcol.hh b/pcol.hh
index 203482b10e..f28617190a 100644
--- a/pcol.hh
+++ b/pcol.hh
@@ -3,7 +3,7 @@
 
 #include "glob.hh"
 #include "boxes.hh"
-#include "list.hh"
+#include "plist.hh"
 #include "item.hh"
 
 /// stuff grouped vertically.
diff --git a/proto.hh b/proto.hh
index ba93e7a526..268eda6b53 100644
--- a/proto.hh
+++ b/proto.hh
@@ -69,7 +69,6 @@ struct Staff_column;
 struct Staff;
 struct Command;
 struct Symbol;
-struct Stretchable_symbol;
 struct Output;
 struct Text_gob;
 struct Voice;
@@ -83,8 +82,9 @@ class Mixed_qp;
 class Paperdef;
 class Score_commands;
 class Parametric_symbol;
-
-
+struct Lookup;
+struct Symtables;
+struct Symtable;
 
 #endif // PROTO_HH
 
diff --git a/pscore.cc b/pscore.cc
index 773554375c..e1c8a7204a 100644
--- a/pscore.cc
+++ b/pscore.cc
@@ -1,5 +1,6 @@
 // utility functions for PScore
 #include "debug.hh"
+#include "paper.hh"
 #include "molecule.hh"
 #include "dimen.hh"
 #include "line.hh"
@@ -95,16 +96,16 @@ PScore::add(PCol *p)
     cols.bottom().add(p);
 }
 
-PScore::PScore()
+PScore::PScore( Paperdef*p)
 {
-    linewidth = convert_dimen(15,"cm");	// default
+    paper_ = p;
 }
 
 void
 PScore::output(Tex_stream &ts)
 {
     int l=1;
-    ts << "% linewidth " << print_dimen(linewidth )+"\n";
+
     for (PCursor<Line_of_score*> lic(lines); lic.ok(); lic++) {
 	ts << "% line of score no. " << l++ <<"\n";
 	ts << lic->TeXstring();
@@ -135,11 +136,13 @@ PScore::OK()const
 	ic->OK();
 #endif
 }
+
 void
 PScore::print() const
 {    
 #ifndef NPRINT
-    mtor << "PScore { width "<<print_dimen(linewidth);
+    mtor << "PScore { paper ";
+    paper_->print();
     mtor << "\ncolumns: ";
     for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
 	cc->print();
diff --git a/pscore.hh b/pscore.hh
index b22582e3f6..58a6910bbd 100644
--- a/pscore.hh
+++ b/pscore.hh
@@ -10,8 +10,7 @@
 
 /// all stuff which goes onto paper
 struct PScore {
-    /// width of paper
-    Real linewidth;
+    Paperdef *paper_;		// indirection.
     
     /// the columns, ordered left to right
     PointerList<PCol *> cols;
@@ -73,7 +72,7 @@ struct PScore {
     void clean_cols();
     void problem_OK()const ;
     void OK()const ;
-    PScore();
+    PScore(Paperdef*);
     void print() const;
 };
 /** notes, signs, symbols in a score can be grouped in two ways:
diff --git a/pstaff.cc b/pstaff.cc
index c922fe9996..255fceeadd 100644
--- a/pstaff.cc
+++ b/pstaff.cc
@@ -1,7 +1,8 @@
 #include "pstaff.hh"
 
-PStaff::PStaff()
+PStaff::PStaff(PScore*ps)
 {
+    pscore_=ps;
     stafsym = 0;
 }
 
diff --git a/pstaff.hh b/pstaff.hh
index 8d17b9dd19..bf33c6b437 100644
--- a/pstaff.hh
+++ b/pstaff.hh
@@ -1,22 +1,22 @@
 #ifndef PSTAFF_HH
 #define PSTAFF_HH
 
-#include "list.hh"
+#include "plist.hh"
 #include "item.hh"
 #include "symbol.hh"
 
 /// items grouped vertically.
-class PStaff {
-
-public:
+struct PStaff {
     Parametric_symbol *stafsym;
-    virtual Symbol get_stafsym(Real width)const=0; // mayybe overkill
+    PScore * pscore_;
+    
+    virtual Symbol get_stafsym(Real width)const=0; // maybe overkill
 
     List<const Spanner*> spans;
     List<Item*> its;
 
     void add(Item*i);
-    PStaff();
+    PStaff(PScore*);
     virtual ~PStaff() {}
 };
 
diff --git a/qlp.cc b/qlp.cc
index c76946e866..3dd8e4227e 100644
--- a/qlp.cc
+++ b/qlp.cc
@@ -4,7 +4,7 @@
 #include "choleski.hh"
 
 void
-Mixed_qp::add_equality_cons(Vector v, double r)
+Mixed_qp::add_equality_cons(Vector , double )
 {
     assert(false);
 }
diff --git a/request.cc b/request.cc
index 27816e5b43..88fdb3349f 100644
--- a/request.cc
+++ b/request.cc
@@ -23,18 +23,49 @@ Note_req::Note_req(Voice_element*v)
     forceacc = false;
 }
 
+int
+Note_req::height() const
+{
+    int s = name -'c';
+    if (s < 0)
+	s+=7;
+    return  s + octave*7;
+}
+
+/****************************************************************/
 Rhythmic_req::Rhythmic_req(Voice_element*v)
      :Request(v)
 {
     balltype = 1;
     dots = 0;
 }
+void
+Rhythmic_req::print() const
+{
+    mtor << "rhythmic: " << balltype ;
+    int d =dots;
+    while (d--)
+	mtor << '.';
+    mtor<<"\n";
+}
+void
+Note_req::print() const
+{
+    mtor << "note: " << name << " oct: "<< octave;
+    Rhythmic_req::print();
+}
 
 Request::Request()
 {
     elt = 0;
 }
 
+void
+Rest_req::print() const
+{
+    mtor << "rest, " ;
+    Rhythmic_req::print();
+}
 
 Real
 wholes(int dur, int dots)
diff --git a/request.hh b/request.hh
index f2dc5f7144..8ebb1468c0 100644
--- a/request.hh
+++ b/request.hh
@@ -5,14 +5,12 @@
 #include "glob.hh"
 #include "string.hh"
 
+/// a voice element wants something printed
 struct Request {
     Voice_element*elt;
-#if 0
-    enum {
-	UNKNOWN, NOTE, REST, LYRIC, SCRIPT, CHORD, BEAM,
-	BRACKET, STEM, SLUR, CRESC, DECRESC, ABSDYNAMIC
-    } tag;
-#endif
+    
+    /****************/
+
     virtual void print()const ;
     virtual Note_req *note() {return 0;}
     virtual Rest_req *rest() {return 0;}
@@ -53,12 +51,17 @@ struct Request {
     beams/stems to look up the balls it has to connect to.  */
 	
 
+/// a request with a duration
 struct Rhythmic_req : Request {
     int balltype;
     int dots;
+    
+    /****************/
+
     Real duration() const;
     Rhythmic_req(Voice_element*);
-    Rhythmic_req*rhythmic() { return this;} 
+    Rhythmic_req*rhythmic() { return this;}
+    void print ()const;
 };
 
 /// Put a note of specified type, height, and with accidental on the staff.
@@ -67,8 +70,14 @@ struct Note_req : Rhythmic_req {
     int octave;
     int accidental;
     bool forceacc;
+    
+    /****************/
+
+    // return height from central c (in halflines)
+    int height()const; 
     Note_req(Voice_element*v);
     Note_req*note() { return this;}
+    virtual void print() const;
 };
 /**
 Staff has to decide if the ball should be hanging left or right. This
@@ -83,7 +92,7 @@ based on ottava commands and the appropriate clef.
 
 ///Put a rest on the staff.
 struct Rest_req : Rhythmic_req {
-
+    void print()const;
     Rest_req(Voice_element*v) : Rhythmic_req(v) {  }
     Rest_req * rest() { return this;}
 };
diff --git a/rhythmstaf.cc b/rhythmstaf.cc
deleted file mode 100644
index 0b9e90e229..0000000000
--- a/rhythmstaf.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "request.hh"
-#include "debug.hh"
-#include "linestaff.hh"
-#include "staff.hh"
-#include "pstaff.hh"
-#include "pscore.hh"
-#include "command.hh"
-#include "molecule.hh"
-#include "rhythmstaf.hh"
-#include "lookupsyms.hh"
-#include "sccol.hh" 
-
-Rhythmic_column::Rhythmic_column(Score_column*s, Rhythmic_staff *rs)
-    : Staff_column(s)
-{
-    the_note = 0;
-    staff_ = rs;
-}
-
-Rhythmic_staff::Rhythmic_staff()
-{
-    theline = new Linestaff(1);
-}
-void
-Rhythmic_staff::set_output(PScore* ps )
-{
-    pscore_ = ps;
-    pscore_->add(theline);
-}
-
-// should integrate handling of BREAK commands into Staff_column
-void
-Rhythmic_column::process_commands( )
-{
-    int breakstat = BREAK_END - BREAK_PRE;
-    for (int i = 0 ; i < s_commands.sz(); i++) {
-	Command *com = s_commands[i];
-	switch (com->code){
-	case INTERPRET:
-	    break;
-	case BREAK_PRE:
-	case BREAK_MIDDLE:
-	case BREAK_POST:
-	case BREAK_END:
-	    score_column->set_breakable();
-	    breakstat = com->code- BREAK_PRE;
-	    break;
-	    
-	case TYPESET:
-	    typeset_command ( com , breakstat);
-	    break;
-	default :
-	    break;
-	}
-	
-    }
-}
-/**
- accept:
-
-    BREAK: all
-    TYPESET: bar, meter
-
-    */
-
-
-
-void
-Rhythmic_column::process_requests()
-{
-    for (int i = 0 ; i < v_elts.sz(); i ++)
-	for (PCursor<Request *> rqc(v_elts[i]->reqs); rqc.ok(); rqc++) {
-	    Request *rq= rqc;
-	    if (rq->rhythmic()){
-		if (the_note){
-		    WARN << "too many notes.\n";
-		    return;
-		}
-		the_note = rq;
-	    }
-	    break;
-	}
-}
-
-
-void
-Rhythmic_column::typeset_command(Command *com, int breakst)
-{
-    Item *i = new Item;
-    Symbol s;
-
-    if (com -> args[0] ==  "BAR" ) {
-	s = Lookup::bar(com->args[1]);	
-    } else if (com->args[0] == "METER") {
-	Parametric_symbol *p = Lookup::meter("general");
-	svec<String> arg( com->args);
-	arg.del(0);
-	s = p->eval(arg);
-    } else
-	assert(false);
-
-    Molecule * m =new Molecule(Atom(s));
-    {
-	Interval wid;
-	svec<Item*> sv(staff_->pscore_->
-		       select_items(staff_->theline, score_column->pcol));
-	for (int j=0; j<sv.sz(); j++) {
-	    wid.unite(sv[j]->output->extent().x);
-	}
-	if (!wid.empty())
-	    m->translate(Offset(wid.max,0));
-    }
-    i->output=m;
-    staff_->pscore_->typeset_item(i, score_column->pcol,
-				  staff_->theline,breakst);
-}
-
-void
-Rhythmic_column::typeset_req(Request *rq)
-{
-    Item *i = new Item;
-    Symbol s;
-    int dots=0;
-
-    if (rq->note())
-	s = Lookup::ball(rq->note()->balltype);
-    if (rq->rhythmic())
-	dots=rq->rhythmic()->dots;
-    if (rq->rest())
-	s = Lookup::rest(rq->rest()->balltype);
-
-    Molecule *m = new Molecule(Atom(s));
-    if (dots) {
-	Symbol d = Lookup::dots(dots);
-	Molecule dm;
-	dm.add(Atom(d));
-	m->add_right(dm);
-    }
-    i->output=m;
-    staff_->pscore_->typeset_item(i, score_column->pcol, staff_->theline );
-}
-
-void
-Rhythmic_staff::grant_requests()
-{
-    for  (PCursor<Staff_column*> cc(cols); cc.ok(); cc++) {
-	Rhythmic_column *rp = (Rhythmic_column*)*cc;
-	if (rp->the_note)
-	    rp->typeset_req( rp->the_note);
-    }
-}
-
-Staff_column*
-Rhythmic_staff::create_col(Score_column*s)
-{
-    Rhythmic_column *rc = new Rhythmic_column(s,this);
-
-    return rc;
-}
-
-Staff *
-get_new_rhythmstaff()
-{
-    return new Rhythmic_staff;
-}
diff --git a/rhythmstaf.hh b/rhythmstaf.hh
deleted file mode 100644
index 69b61ec487..0000000000
--- a/rhythmstaf.hh
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-  rhythmstaf.hh -- part of LilyPond
-
-  (c) 1996 Han-Wen Nienhuys
-*/
-
-#ifndef RHYTHMSTAF_HH
-#define RHYTHMSTAF_HH
-#include "stcol.hh"
-
-struct Rhythmic_staff;
-
-/// column of Rhythmic_staff
-struct Rhythmic_column : Staff_column {
-    // mega-stupido. only do notes, one at a time
-    Request *the_note;
-    Rhythmic_staff* staff_;
-
-    /****************/
-    
-    void typeset_req(Request *rq);
-    void take_request(Request *rq);
-    void typeset_command(Command *, int brs);
-    void process_commands( );
-    void process_requests();
-
-    Rhythmic_column(Score_column*s,Rhythmic_staff*rs);
-};
-
-
-/// simple percussion staff
-struct Rhythmic_staff : Staff {
-    /// indirection to the PStaff.
-    PStaff *theline;
-
-    /****************/
-    void set_output(PScore *);
-    void process_commands( PCursor<Command*> &where);
-
-    void grant_requests();
-    Staff_column * create_col(Score_column*);
-    Rhythmic_staff();
-};
-
-
-#endif // RHYTHMSTAF_HH
-
-
diff --git a/rhythmstaff.cc b/rhythmstaff.cc
new file mode 100644
index 0000000000..4e564bdf88
--- /dev/null
+++ b/rhythmstaff.cc
@@ -0,0 +1,52 @@
+#include "molecule.hh"
+#include "linestaff.hh"
+#include "rhythmstaff.hh"
+#include "paper.hh"
+#include "sccol.hh" 
+
+
+void
+Rhythmic_staff::set_output(PScore*ps)
+{
+    theline = new Linestaff(1,ps);
+    Simple_staff::set_output(ps);
+}
+
+
+void
+Rhythmic_column::typeset_command(Command *com, int breakst)
+{
+    Item *i = create_command_item(com);
+    i->output->translate(Offset(0,
+				-staff_->score_->paper_->standard_height()/2));
+    typeset_item(i, breakst);
+}
+
+void
+Rhythmic_column::typeset_req(Request *rq)
+{
+    Item *i =create_req_item(rq);
+    typeset_item(i);
+}
+
+/*
+  creation
+  */
+Staff *
+get_new_rhythmstaff()
+{
+    return new Rhythmic_staff;
+}
+
+
+Staff_column*
+Rhythmic_staff::create_col(Score_column*s)
+{
+    return new Rhythmic_column(s,this);
+}
+
+Rhythmic_staff*
+Rhythmic_staff::clone() const
+{
+    return new Rhythmic_staff(*this);
+}
diff --git a/rhythmstaff.hh b/rhythmstaff.hh
new file mode 100644
index 0000000000..7fe7c6a887
--- /dev/null
+++ b/rhythmstaff.hh
@@ -0,0 +1,35 @@
+/*
+  rhythmstaf.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef RHYTHMSTAF_HH
+#define RHYTHMSTAF_HH
+
+#include "simplestaff.hh"
+
+/// all notes on one line
+struct Rhythmic_staff : public Simple_staff
+{
+    //  Rhythmic_staff();
+    Staff_column * create_col(Score_column*);
+    virtual void set_output(PScore *);
+    virtual Rhythmic_staff*clone()const;
+};
+
+/// this does the typesetting
+struct Rhythmic_column : public Simple_column {
+    virtual void typeset_req(Request *rq);
+    virtual void typeset_command(Command *, int brs);
+  
+
+//    virtual void typeset_item(Item *rq, int=1);
+    Rhythmic_column(Score_column*s,Simple_staff*rs) :
+	Simple_column(s,rs) { }
+//    virtual Rhythmic_column*clone()const;
+};
+
+#endif // RHYTHMSTAF_HH
+
+
diff --git a/scommands.hh b/scommands.hh
index ee3b4591ab..9106f2bfcc 100644
--- a/scommands.hh
+++ b/scommands.hh
@@ -7,7 +7,7 @@
 #include "proto.hh"
 #include "command.hh"
 #include "vray.hh"
-#include "list.hh"
+#include "plist.hh"
 
 struct Score_commands : public PointerList<Command*> {
     void process_add(Command);
diff --git a/score.cc b/score.cc
index 3c95fd1790..097e2aa50d 100644
--- a/score.cc
+++ b/score.cc
@@ -29,6 +29,7 @@ Score::output(String s)
 void
 Score::process()
 {
+    *mlog << "Processing ...";
     set(commands_->parse(last()));
     commands_->print();
     
@@ -40,7 +41,7 @@ Score::process()
     /// distribute commands to disciples
     distribute_commands();
     
-    pscore_ = new PScore;
+    pscore_ = new PScore(paper_);
     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
 	sc->set_output(pscore_);
 	sc->process();
@@ -52,9 +53,11 @@ Score::process()
     clean_cols();
     OK();
     //    print();
+    *mlog << "Calculating ... ";
     pscore_->calc_breaking();
     // TODO: calculate vertical structs
     // TODO: calculate mixed structs.
+    *mlog << "\n";
 }
 
 // remove empty cols with no spacing attached.
diff --git a/score.hh b/score.hh
index e58f87f058..176d7fa47a 100644
--- a/score.hh
+++ b/score.hh
@@ -2,7 +2,7 @@
 #define SCORE_HH
 #include "vray.hh"
 #include "proto.hh"
-#include "list.hh"
+#include "plist.hh"
 
 
 /// the total music def of one movement
diff --git a/simpleprint.cc b/simpleprint.cc
new file mode 100644
index 0000000000..91b7761738
--- /dev/null
+++ b/simpleprint.cc
@@ -0,0 +1,79 @@
+#include "lookupsyms.hh"
+#include "request.hh"
+#include "pscore.hh"
+#include "paper.hh"
+#include "simplestaff.hh"
+#include "molecule.hh"
+#include "sccol.hh"
+
+Item *
+Simple_column::create_req_item(Request *rq)
+{
+    Item *i = new Item;
+    Symbol s;
+    int dots=0;
+
+    if (rq->note())
+	s = staff_->paper()->lookup_->ball(rq->note()->balltype);
+    else if (rq->rest())
+	s = staff_->paper()->lookup_->rest(rq->rest()->balltype);
+
+    if (rq->rhythmic())
+	dots=rq->rhythmic()->dots;
+
+
+    Molecule *m = new Molecule(Atom(s));
+    if (dots) {
+	Symbol d = staff_->paper()->lookup_->dots(dots);
+	Molecule dm;
+	dm.add(Atom(d));
+	m->add_right(dm);
+    }
+    i->output=m;
+    return i;
+}
+Item *
+Simple_column::create_command_item(Command *com)
+{
+    Item *i = new Item;
+    Symbol s;
+
+    if (com -> args[0] ==  "BAR" ) {
+	s = staff_->paper()->lookup_->bar(com->args[1]);	
+    } else if (com->args[0] == "METER") {
+	Parametric_symbol *p = staff_->paper()->lookup_->meter("general");
+	svec<String> arg( com->args);
+	arg.del(0);
+	s = p->eval(arg);
+    } else
+	assert(false);
+
+    Molecule * m =new Molecule(Atom(s));
+    {
+	Interval wid;
+	svec<Item*> sv(staff_->pscore_->
+		       select_items(staff_->theline, score_column->pcol));
+	for (int j=0; j<sv.sz(); j++) {
+	    wid.unite(sv[j]->output->extent().x);
+	}
+	if (!wid.empty())
+	    m->translate(Offset(wid.max,0));
+    }
+    i->output=m;
+    return i;
+}
+
+void
+Simple_column::typeset_item(Item *i, int breakst)
+{
+    // ugh
+    staff_->pscore_->typeset_item(i, score_column->pcol,
+				  staff_->theline,breakst);
+}
+
+void
+Simple_staff::set_output(PScore* ps )
+{
+    pscore_ = ps;
+    pscore_->add(theline);
+}
diff --git a/simplestaff.cc b/simplestaff.cc
new file mode 100644
index 0000000000..763a9ed393
--- /dev/null
+++ b/simplestaff.cc
@@ -0,0 +1,86 @@
+#include "request.hh"
+#include "debug.hh"
+#include "staff.hh"
+#include "command.hh"
+#include "simplestaff.hh"
+#include "sccol.hh" 
+
+
+
+
+Simple_column::Simple_column(Score_column*s, Simple_staff *rs)
+    : Staff_column(s)
+{
+    the_note = 0;
+    staff_ = rs;
+}
+
+Simple_staff::Simple_staff()
+{
+    theline = 0;
+}
+
+// should integrate handling of BREAK commands into Staff_column
+void
+Simple_column::process_commands( )
+{
+    int breakstat = BREAK_END - BREAK_PRE;
+    for (int i = 0 ; i < s_commands.sz(); i++) {
+	Command *com = s_commands[i];
+	switch (com->code){
+	case INTERPRET:
+	    break;
+	case BREAK_PRE:
+	case BREAK_MIDDLE:
+	case BREAK_POST:
+	case BREAK_END:
+	    score_column->set_breakable();
+	    breakstat = com->code- BREAK_PRE;
+	    break;
+	    
+	case TYPESET:
+	    typeset_command ( com , breakstat);
+	    break;
+	default :
+	    break;
+	}	
+    }
+}
+/**
+ accept:
+
+    BREAK: all
+    TYPESET: bar, meter
+
+    */
+
+
+
+void
+Simple_column::process_requests()
+{
+    for (int i = 0 ; i < v_elts.sz(); i ++)
+	for (PCursor<Request *> rqc(v_elts[i]->reqs); rqc.ok(); rqc++) {
+	    Request *rq= rqc;
+	    if (rq->rhythmic()){
+		if (the_note){
+		    WARN << "too many notes.\n";
+		    return;
+		}
+		the_note = rq;
+	    }
+	    break;
+	}
+}
+
+void
+Simple_staff::grant_requests()
+{
+    for  (PCursor<Staff_column*> cc(cols); cc.ok(); cc++) {
+	Simple_column *rp = (Simple_column*)*cc;
+	if (rp->the_note)
+	    rp->typeset_req( rp->the_note);
+    }
+}
+
+
diff --git a/simplestaff.hh b/simplestaff.hh
new file mode 100644
index 0000000000..e2efafe398
--- /dev/null
+++ b/simplestaff.hh
@@ -0,0 +1,59 @@
+/*
+  simplestaff.hh -- part of LilyPond
+
+  (c) 1996 Han-Wen Nienhuys
+*/
+
+#ifndef SIMPLESTAFF_HH
+#define SIMPLESTAFF_HH
+
+#include "stcol.hh"
+#include "staff.hh"
+/*
+   mega-stupido staffs and cols: they do notes one at each moment.   
+   */
+
+struct Simple_staff;
+
+/// column of Simple_staff: store one request
+struct Simple_column : Staff_column {
+
+    Request *the_note;
+    Simple_staff* staff_;
+
+    /****************/
+    
+    virtual void typeset_req(Request *rq)=0;
+    virtual void typeset_command(Command *, int brs)=0;
+    virtual void typeset_item(Item *, int=1);
+
+    Item *create_command_item(Command *com);
+    Item *create_req_item(Request *rq);
+    void take_request(Request *rq);
+    
+    virtual void process_commands( );
+    virtual void process_requests();
+
+    Simple_column(Score_column*s,Simple_staff*rs);
+};
+
+
+/// Simple  staff: one note at a time
+struct Simple_staff : Staff {
+    /// indirection to the PStaff.
+    PStaff *theline;
+
+    /****************/
+    virtual void set_output(PScore *);
+
+    void process_commands( PCursor<Command*> &where);
+    void grant_requests();
+//    virtual Staff*clone()const;
+
+    Simple_staff();
+};
+
+#endif // SIMPLESTAFF_HH
+
+
+
diff --git a/staff.cc b/staff.cc
index 7dd2666dc9..8b5c0782c5 100644
--- a/staff.cc
+++ b/staff.cc
@@ -3,6 +3,20 @@
 #include "sccol.hh"
 #include "debug.hh"
 
+Staff::Staff(Staff const&src)
+{
+    PL_copy(voices,src.voices);
+    PL_copy(commands,src.commands);
+    assert(!cols.size());	// cols is a runtime field.
+
+    score_ = src.score_;
+    pscore_ = src.pscore_;
+}
+
+Paperdef*
+Staff::paper() const{
+    return score_->paper_;
+}
 
 void
 Staff::clean_cols()
@@ -23,7 +37,7 @@ Staff::get_col(Real w, bool mus)
     assert(sc->when == w);
     PCursor<Staff_column *> stc(cols);
     for (; stc.ok(); stc++) {
-	if (*sc  < *stc->score_column)
+	if (*stc->score_column > *sc) // too far
 	    break;
 	if (sc == stc->score_column)
 	    return stc;
@@ -131,7 +145,8 @@ Staff::OK() const
 
 
 Real
-Staff::last() const {
+Staff::last() const
+{
     Real l = 0.0;
     for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
 	l = MAX(l, vc->last());
@@ -143,20 +158,18 @@ Staff::last() const {
 void
 Staff::print() const
 {
-        #ifndef NPRINT
-
+#ifndef NPRINT
     mtor << "Staff {\n";
     for (PCursor<Voice*> vc(voices); vc.ok(); vc++) {
 	vc->print();
 	
     }
     mtor <<"}\n";
-    #endif
+#endif
 }
 
 Staff::Staff()
 {
     score_ =0;
-    pscore_=0;
-    
+    pscore_=0;    
 }
diff --git a/staff.hh b/staff.hh
index 3d39c6e78b..f2c7294de0 100644
--- a/staff.hh
+++ b/staff.hh
@@ -13,6 +13,8 @@ struct Staff {
 
     /// commands in chronological order
     PointerList<Command *> commands;
+
+    /// runtime field
     PointerList<Staff_column*> cols;
 
     /// indirections to the Score and PScore
@@ -20,11 +22,11 @@ struct Staff {
     PScore *pscore_;
 
     /****************************************************************/
-    
+    Staff(const Staff&src);
     void add_voice(Voice *v);
     void add_staff_column(Staff_column *sp);
 
-	 
+    Paperdef*paper()const;
     /// interpret all requests and add items to #destination#.
     void process();
     /**
@@ -53,12 +55,11 @@ struct Staff {
     /****************************************************************
       VIRTUALS
     ****************************************************************/
-    
+    virtual Staff*clone()const=0;    
     virtual void set_output(PScore * destination)=0;
     virtual void grant_requests()=0;    
     virtual Staff_column * create_col(Score_column * )=0;
     virtual ~Staff() { }
-
 };
 #endif
 
diff --git a/stcol.hh b/stcol.hh
index 060d585fde..1d8b09c61e 100644
--- a/stcol.hh
+++ b/stcol.hh
@@ -9,6 +9,7 @@
 #include "proto.hh"
 #include "vray.hh"
 
+/// store simultaneous requests
 struct Staff_column {
     Score_column *score_column;
 
@@ -23,6 +24,7 @@ struct Staff_column {
     /****************************************************************
       VIRTUAL
     ****************************************************************/
+    //virtual Staff_column *clone() const=0;
     virtual void process_requests()=0;
     virtual void process_commands()=0;
     virtual ~Staff_column() { }
diff --git a/symbol.cc b/symbol.cc
index d67049cefa..907f1d7282 100644
--- a/symbol.cc
+++ b/symbol.cc
@@ -30,6 +30,3 @@ Parametric_symbol::eval(String args1,String arg2)const
     return eval(a);
 }
 
-Parametric_symbol::~Parametric_symbol()
-{
-}
diff --git a/symbol.hh b/symbol.hh
index 6d6ed1acbe..4f26e04e66 100644
--- a/symbol.hh
+++ b/symbol.hh
@@ -2,6 +2,7 @@
 #define SYMBOL_HH
 #include "string.hh"
 #include "boxes.hh"
+#include "proto.hh"
 
 struct Symbol {
     String tex;
@@ -12,11 +13,15 @@ struct 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();    
+    virtual ~Parametric_symbol(){}
 };
 
 #endif
diff --git a/symbol.ini b/symbol.ini
index 26c0a31bff..3671dae8af 100644
--- a/symbol.ini
+++ b/symbol.ini
@@ -1,27 +1,31 @@
+
+
+
+symboltables
 # index TeXstring, 	xmin xmax ymin ymax
 
 # be careful with editing this:
 # the "index" entry is hardwired into lilypond.
 
 table balls
-	1	\wholeball	-5pt	5pt	-1pt	1pt
-	2	\halfball	-5pt	5pt	-1pt	1pt
-	4	\quartball	-5pt	5pt	-1pt	1pt
+	1	\wholeball	-5pt	5pt	-2.5pt	2.5pt
+	2	\halfball	-5pt	5pt	-2.5pt	2.5pt
+	4	\quartball	-5pt	5pt	-2.5pt	2.5pt
 end
 
 table bars
 	empty	\emptybar	0pt	0pt	0pt	0pt
-	|	\maatstreep	0pt	1pt 	-8pt	8pt
-	||	\finishbar	0pt	2pt	-8pt	8pt
+	|	\maatstreep	0pt	1pt 	-12pt	12pt
+	||	\finishbar	0pt	2pt	-12pt	12pt
 end
 
 table rests
 	1	\wholerest		-5pt	1pt	-1pt	1pt
 	2	\halfrest		-5pt	1pt	-1pt	1pt
-	4	\cquartrest		-5pt	2pt	-5pt	5pt
-	8	\ceighthrest		-5pt	1pt	-1pt	1pt
-	16	\csixteenthrest		-5pt	1pt	-1pt	1pt
-	32	\cthirtysecondrest	-1pt	1pt	-1pt	1pt
+	4	\quartrest		-5pt	2pt	-5pt	5pt
+	8	\eighthrest		0pt	5pt	0pt	8pt
+	16	\sixteenthrest		0pt	6pt	0pt	12pt
+	32	\thirtysecondrest	0pt	6pt	0pt	16pt
 end
 
 table meters
@@ -39,4 +43,5 @@ table dots
 	1	\lsingledot		0pt	8pt	-1pt	1pt
 	2	\ldoubledot		0pt	12pt	-1pt	1pt
 	3	\ltripledot		0pt	16pt	-1pt	1pt
-end
+end 
+end # symboltables
\ No newline at end of file
diff --git a/symtable.cc b/symtable.cc
index b4de607b8d..eedb25a4e5 100644
--- a/symtable.cc
+++ b/symtable.cc
@@ -7,9 +7,6 @@
 #include "symtable.hh"
 
 
-
-
-
 Symbol 
 Symtable::lookup(String s) const
 {
@@ -25,21 +22,16 @@ Symtable::lookup(String s) const
 Symtable* 
 Symtables::operator()(String s) 
 {
-    if (!done_reading){	// read on demand
-	*mlog << '(' << fname ;
-	read();
-	done_reading = true;
-	*mlog << ")\n";
-    }
     return Assoc<String, Symtable*>::operator[](s);
 } 
 
 void
-Symtables::read()
+Symtables::read(Text_db &symini)
 {
-     Text_db symini(fname);
      while (!symini.eof()) {
 	 Text_record  r(  symini++);
+	 if (r[0] == "end" )
+	     return;
 	 assert (r[0] == "table");
 	 
 	 String tabnam = r[1];
diff --git a/symtable.hh b/symtable.hh
index 73c4079e70..a1443a7d3b 100644
--- a/symtable.hh
+++ b/symtable.hh
@@ -13,12 +13,7 @@ struct  Symtable : public Assoc<String, Symbol> {
 
 
 struct Symtables : private Assoc<String, Symtable*> {
-    String fname;
-    bool done_reading;
-    Symtables(String s) : fname (s) {
-	done_reading = false;
-    }
-    void read() ;
+    void read(Text_db&) ;
     Symtable* operator()(String s);
 
 };
diff --git a/table.cc b/table.cc
index da2af9575e..5352574399 100644
--- a/table.cc
+++ b/table.cc
@@ -1,12 +1,14 @@
 #include "glob.hh"
 #include "debug.hh"
 #include "string.hh"
+#include "identifier.hh"
 #include "keyword.hh"
 #include "parser.hh"
 
 static Keyword_ent  the_key_tab[]={
     "voice", VOICE,
     "rhythmstaff", RHYTHMSTAFF,
+    "melodicstaff", MELODICSTAFF,
     "score", SCORE,
     "bar", BAR,
     "output", OUTPUT,
@@ -20,6 +22,7 @@ static Keyword_ent  the_key_tab[]={
     "unitspace", UNITSPACE,
     "skip", SKIP,
     "commands", COMMANDS,
+    "staff", STAFF,
     0,0
 } ;
 
@@ -37,7 +40,13 @@ Identifier*
 lookup_identifier(String s)
 {
     if (!the_id_tab.elt_query(s))
-	 the_id_tab[s]= new Identifier;
+	return 0;
     
     return the_id_tab[s];
 }
+
+void
+add_identifier(Identifier*i)
+{    
+    the_id_tab[i->name] = i;
+}
diff --git a/template1.cc b/template1.cc
index b7c453b6e0..01aba139e2 100644
--- a/template1.cc
+++ b/template1.cc
@@ -1,12 +1,14 @@
 #include "line.hh"
 
-#include "list.hh"
+#include "plist.hh"
 #include "pcol.hh"
 #include "item.hh"
 #include "request.hh"
 #include "command.hh"
 
 #include "list.cc"
+
+#include "plist.cc"
 #include "cursor.cc"
 #define PLC_instantiate(a) PL_instantiate(a); PL_instantiate(const a)
 
diff --git a/template2.cc b/template2.cc
index 08f2eea880..1c54a2cb94 100644
--- a/template2.cc
+++ b/template2.cc
@@ -7,6 +7,7 @@
 #include "stcol.hh"
 
 #include "list.cc"
+#include "plist.cc"
 #include "cursor.cc"
 PL_instantiate(Score_column);
 PL_instantiate(Staff_column);
diff --git a/template3.cc b/template3.cc
index 6f2e92104c..92921bb29a 100644
--- a/template3.cc
+++ b/template3.cc
@@ -2,6 +2,7 @@
 #include "command.hh"
 #include "molecule.hh"
 #include "list.cc"
+#include "plist.cc"
 #include "cursor.cc"
 PL_instantiate(Atom);
 PL_instantiate(Command);
diff --git a/voice.hh b/voice.hh
index b580972b23..b409fa4cd3 100644
--- a/voice.hh
+++ b/voice.hh
@@ -2,7 +2,7 @@
 #define VOICE_HH
 
 
-#include "list.hh"
+#include "plist.hh"
 #include "request.hh"
 
 /// class for  horizontal stuff.
@@ -28,7 +28,7 @@ struct Voicegroup {
     /// don't know how to identify these.
 };
 
-/// 
+/// one horizontal bit. 
 struct Voice_element {
     Real duration;
     const Voicegroup *group;
@@ -37,6 +37,9 @@ struct Voice_element {
 
     List<const Item *> granted_items;
     List<const Spanner *> granted_spanners;
+
+    /****************/
+    
     void add(Request*);
     Voice_element();
 
-- 
2.39.5