]> git.donarmstrong.com Git - lilypond.git/commitdiff
release: 1.5.3 release/1.5.3
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 29 Jul 2001 13:54:28 +0000 (15:54 +0200)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 29 Jul 2001 13:54:28 +0000 (15:54 +0200)
==========

* Starting pagenumber (Mark Hindley)

* Ancient font patch (Juergen Reuter) [WARNING: FONT UPDATE!]

* Bugfix: don't  put grace beams on non grace notes, and vice versa.

* etf2ly:
  - miserable try at importing repeatbars and volta brackets;
  - import articulation defs (IX tag)
  - revamped file reading logic. Now much cleaner.

* Experimental regular-spacing support: try to space regular runs of
notes equidistantly.

1.5.2.j

26 files changed:
CHANGES
INSTALL.txt
VERSION
input/test/ancient-font.ly
input/test/manual-volta.ly [deleted file]
input/test/repeat-manual.ly [new file with mode: 0644]
input/test/spacing-regular.ly [new file with mode: 0644]
lily/auto-beam-engraver.cc
lily/beam-engraver.cc
lily/include/spacing-spanner.hh
lily/include/spring.hh
lily/key-item.cc
lily/local-key-item.cc
lily/regular-spacing-engraver.cc [new file with mode: 0644]
lily/spacing-spanner.cc
lily/spring.cc
lily/volta-engraver.cc
make/out/lilypond.lsm
make/out/lilypond.redhat.spec
make/out/lilypond.suse.spec
mf/feta-klef.mf
mf/feta-toevallig.mf
scm/basic-properties.scm
scm/clef.scm
scm/foo.scm [deleted file]
scripts/etf2ly.py

diff --git a/CHANGES b/CHANGES
index 22fd53ad4bfc5c933dfd05031dc95b47977f9f20..1ed44c2eaf5ce219dd2ba38840c7081108d249fe 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,20 @@
+1.5.2.hwn1
+==========
+
+* Starting pagenumber (Mark Hindley)
+
+* Ancient font patch (Juergen Reuter) [WARNING: FONT UPDATE!]
+
+* Bugfix: don't  put grace beams on non grace notes, and vice versa.
+
+* etf2ly:
+  - miserable try at importing repeatbars and volta brackets;
+  - import articulation defs (IX tag)
+  - revamped file reading logic. Now much cleaner.
+
+* Experimental regular-spacing support: try to space regular runs of
+notes equidistantly.
+
 1.5.2.jcn2
 ==========
 
index 6a8b664b589a33dcdd6693ba2a7f3bfbdfda6d97..22e59ba08c786630ccde8b0561bc391cfaa1ce5e 100644 (file)
@@ -26,7 +26,7 @@ INSTALL - compiling and installing GNU LilyPond
     Mandrake
     Debian GNU/Linux
   Problems
-    Debian GNU/Linux unstable gcc-3.0
+    FLex-2.5.4a and gcc-3.0
     NetBSD
     Solaris:
     AIX
@@ -270,18 +270,24 @@ profiling.  Then I'd use the following for the normal build,
 Emacs mode
 ==========
 
-   An emacs mode for LilyPond is included with the source archive as
-`lilypond-mode.el' and `lilypond-font-lock.el'.  If you have an RPM, it
-is in `/usr/share/doc/lilypond-X/'.  You have to install it yourself.
+   An Emacs mode for entering music and running LilyPond is included
+with the source archive as `lilypond-mode.el' and
+`lilypond-font-lock.el'.  You should install these files somewhere in
+your LOAD-PATH.  If you have installed a precompiled LilyPond package,
+these files can be found in `/usr/share/doc/lilypond-x.y.z/'.
 
-   Add this to your `~/.emacs' or `~/.emacs.el':
+   Add this to your `~/.emacs' or `~/.emacs.el', or install this file
+in Emacs' `site-start.d':
+         ;;; lilypond-init.el --- Startup code for LilyPond mode
+     
          (load-library "lilypond-mode.el")
          (setq auto-mode-alist
            (cons '("\\.ly$" . LilyPond-mode) auto-mode-alist))
          (add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))
 
    If you have the latest LilyPond-1.4.x Debian package, LilyPond-mode
-is automatically loaded, so you need not modify your `~/.emacs' file.
+is automatically loaded, you not even need to modify your `~/.emacs'
+file.
 
 Compiling for distributions
 ===========================
@@ -469,17 +475,19 @@ bug reports to <bug-lilypond@gnu.org>.
 
    Bugs that are not fault of LilyPond are documented here.
 
-Debian GNU/Linux unstable gcc-3.0
----------------------------------
+FLex-2.5.4a and gcc-3.0
+-----------------------
 
-   Flex (2.5.4a-11) in unstable does not produce g++-3.0 compliant C++
-code.  To compile LilyPond with gcc-3.0 you may do:
+   Flex 2.5.4a does not produce g++-3.0 compliant C++ code.  To compile
+LilyPond with gcc-3.0 you may do:
 
              CC=gcc-3.0 CXX=g++-3.0 ./configure --enable-config=gcc-3.0
              make conf=gcc-3.0 -C lily out-gcc-3.0/lexer.cc
              patch -p1 < lexer-gcc-3.0.patch
              make conf=gcc-3.0 -C lily
 
+   Note that this is fixed in Debian/unstable for flex >= 2.5.4a-13.
+
 NetBSD
 ------
 
diff --git a/VERSION b/VERSION
index 61251ac53280dd7eeaf40f263de494255b5a06fd..a522ff62608a9f0398fffe4b19f176d0a7b8d4fd 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,8 +1,8 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=5
-PATCH_LEVEL=2
-MY_PATCH_LEVEL=jcn2
+PATCH_LEVEL=3
+MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
index 5c31587b15cff5623e8676f49110d7fa2a65906e..703d5b2f04d8361d1686f2e3dca864fea70ac2f0 100644 (file)
@@ -10,6 +10,7 @@
 
 global =  \notes {
     \property Score.timing = ##f
+%   \property Score.forceAccidental = ##t
 %   \property Staff.TimeSignature \override #'style = #'old
 }
 
@@ -22,11 +23,13 @@ upperVoice =  \context Staff = upperVoice <
       #'line-count = #4
 
     \notes \transpose c' {
-       \property Voice.NoteHead \override #'style = #'mensural
-       \property Voice.Stem \override #'stem-centered = ##t
+       \property Staff.KeySignature \override #'style = #'vaticana
+       \property Staff.Accidentals \override #'style = #'vaticana
        \property Staff.Custos \override #'style = #'vaticana
+       \property Voice.NoteHead \override #'style = #'mensural
+       \key es \major
        \clef "vaticana_fa2"
-       c2 d e f g
+       cis!2 des! e! fis! ges!
 
 %      \property Staff.clefGlyph = #"clefs-vaticana_do"
 %      \property Staff.clefPosition = #1
@@ -34,27 +37,33 @@ upperVoice =  \context Staff = upperVoice <
        \clef "vaticana_do2"
 
        a b c'
-       b a g f
+       b as gis fes
        \clef "vaticana_fa1"
-       e d c1 \bar "|"
+       es dis ces1 \bar "|"
 
+       \property Staff.KeySignature \override #'style = #'medicaea
+       \property Staff.Accidentals \override #'style = #'medicaea
        \property Staff.Custos \override #'style = #'medicaea
+       \property Voice.NoteHead \override #'style = #'mensural
        \clef "medicaea_fa2"
-       c2 d e f g
+       ces2 des es fes ges
        \clef "medicaea_do2"
-       a b c'
-       b a g f
+       as bes ces'
+       bes as ges fes
        \clef "medicaea_fa1"
-       e d c1 \bar "|"
+       es des ces1 \bar "|"
 
+       \property Staff.KeySignature \override #'style = #'hufnagel
+       \property Staff.Accidentals \override #'style = #'hufnagel
        \property Staff.Custos \override #'style = #'hufnagel
+       \property Voice.NoteHead \override #'style = #'mensural
        \clef "hufnagel_fa2"
-       c2 d e f g
+       ces!2 des! es! fes! ges!
        \clef "hufnagel_do2"
-       a b c'
-       b a g f
-       \clef "hufnagel_fa1"
-       e d c1 \bar "||"
+       as! bes! ces'!
+       bes! as! ges! fes!
+       \clef "hufnagel_do_fa"
+       es! des! ces!1 \bar "||"
     }
 >
 
@@ -67,55 +76,57 @@ lowerVoice =  \context Staff = lowerNotes <
       #'line-count = #5
     
     \notes \transpose c' {
-        \property Voice.NoteHead \override #'style = #'mensural
-       \property Voice.Stem \override #'stem-centered = ##t
+       \property Staff.KeySignature \override #'style = #'mensural
+       \property Staff.Accidentals \override #'style = #'mensural
        \property Staff.Custos \override #'style = #'mensural
-       \clef "mensural1_c2"
-       c2 d e f g
+        \property Voice.NoteHead \override #'style = #'mensural
+       \key a \major
+       \clef "neo_mensural_c2"
+       c2 dis es fis ges
         \property Staff.forceClef = ##t
-       \clef "mensural1_c2"
-       a b c'
-       b a g f
-       \clef "mensural2_c2"
+       \clef "neo_mensural_c2"
+       ais bes cis'
+       bis as gis fes
+       \clef "petrucci_c2"
        e d c1 \bar "|"
 
-       \clef "mensural2_c2"
+       \clef "petrucci_c2"
        c2 d e f g
         \property Staff.forceClef = ##t
-       \clef "mensural3_c2"
+       \clef "mensural_c2"
        a b c'
        b a g f
-       \clef "mensural3_c2"
+       \clef "mensural_g"
        e d c1 \bar "|"
 
-       \clef "mensural1_f"
+       \clef "petrucci_f"
        c2 d e f g
         \property Staff.forceClef = ##t
-       \clef "mensural1_f"
+       \clef "petrucci_f"
        a b c'
        b a g f
-       \clef "mensural2_f"
+       \clef "mensural_f"
        e d c1 \bar "|"
 
         \property Staff.forceClef = ##t
-       \clef "mensural2_f"
+       \clef "mensural_f"
        c2 d e f g
        \clef "mensural_g"
-       a' b' c''
-       b' a' g' f'
+       as'! bes'! cis''!
+       bes'! as'! gis'! fis'!
         \property Staff.forceClef = ##t
        \clef "mensural_g"
        e' d' c'1 \bar "|"
 
         \property Staff.forceClef = ##t
-       \clef "mensural_g"
+       \clef "petrucci_g"
        c'2 d' e' f' g'
-       \clef "hufnagel_do_fa"
-       a b c'
-       b a g f
+       \clef "petrucci_g"
+       as'! bes'! cis''!
+       bes'! as'! gis'! fis'!
         \property Staff.forceClef = ##t
-       \clef "hufnagel_do_fa"
-       e d c1 \bar "||"
+       \clef "mensural_g"
+       es'! des'! cis'!1 \bar "||"
     }
 >
 
@@ -128,6 +139,7 @@ lowerVoice =  \context Staff = lowerNotes <
 %      \paperTwentysix
        linewidth = 17.25\cm
        textheight = 26.0\cm
+       stafflinethickness = \staffspace / 5.0
        indent = 0.0
        \translator {
            \StaffContext
diff --git a/input/test/manual-volta.ly b/input/test/manual-volta.ly
deleted file mode 100644 (file)
index 7f9042d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-\version "1.3.146"
-
-
-\score { \notes {
-% First a normal looking repeat:
- c2 c
-    \property Score.repeatCommands = #'((volta "1."))
- c c
-    \property Score.repeatCommands = #'((volta #f) end-repeat (volta "2."))
- c c
-    \property Score.repeatCommands = #'((volta #f))
-% Then a more strange one:
- c c
-    \property Score.repeatCommands = #'((volta "93") end-repeat)
- c c
-    \property Score.repeatCommands = #'((volta #f))
- c c
-}
-}
diff --git a/input/test/repeat-manual.ly b/input/test/repeat-manual.ly
new file mode 100644 (file)
index 0000000..ae47e1b
--- /dev/null
@@ -0,0 +1,20 @@
+
+\version "1.3.146"
+
+
+\score { \notes {
+% First a normal looking repeat:
+ c2 c
+    \property Score.repeatCommands = #'((volta "1."))
+ c c
+    \property Score.repeatCommands = #'((volta #f) end-repeat (volta "2."))
+ c c
+    \property Score.repeatCommands = #'((volta #f))
+% Then a more strange one:
+ c c
+    \property Score.repeatCommands = #'((volta "93") end-repeat)
+ c c
+    \property Score.repeatCommands = #'((volta #f))
+ c c
+}
+}
diff --git a/input/test/spacing-regular.ly b/input/test/spacing-regular.ly
new file mode 100644 (file)
index 0000000..903ced2
--- /dev/null
@@ -0,0 +1,21 @@
+\header
+{
+ texidoc = "regularSpacingDelta is an experimental feature that
+ tries to generate regular spacing for regular notes."
+}
+
+\score { \notes \relative c'' {
+< \context Staff {
+
+c4 c4 c4 }
+\context Staff =SB  { c8 c8   c4 c4 }
+>}
+\paper{
+linewidth = -1.
+\translator { \ScoreContext
+\consists "Regular_spacing_engraver"
+
+regularSpacingDelta = #(make-moment 1 4 )
+}
+}
+}
index 58f289b822f0dcb231a1d5cd396acd5f764f9bff..94671aabf05b43b3a9dbc2aa418c16d6e2799704 100644 (file)
@@ -58,7 +58,6 @@ private:
 
   int count_i_;
   Moment last_add_mom_;
-
   /*
     Projected ending of the  beam we're working on.
    */
@@ -251,6 +250,8 @@ Auto_beam_engraver::begin_beam ()
   grouping_p_ = new Beaming_info_list;
   beam_start_moment_ = now_mom ();
   beam_start_location_ = *unsmob_moment (get_property ("measurePosition"));
+
+
 }
 
 
@@ -394,6 +395,14 @@ Auto_beam_engraver::acknowledge_grob (Grob_info info)
          return;
        }
 
+
+      /*
+       ignore grace notes.
+       */
+      if (bool (beam_start_location_.grace_mom_) != bool (now_mom ().grace_mom_))
+       return ;
+       
+      
       Moment dur = unsmob_duration (rhythmic_req->get_mus_property ("duration"))->length_mom ();
       /* FIXME:
 
index 4445b79643e4192f3dd68bc5a82cec6ef988014e..7b506953c8eb1904381b761bbffae8119f0462a5 100644 (file)
@@ -166,8 +166,8 @@ Beam_engraver::create_grobs ()
 
       beam_start_location_ = mp;
       beam_start_mom_ = now_mom ();
-      beam_info_p_ = new Beaming_info_list;
       
+      beam_info_p_ = new Beaming_info_list;
       
       /* urg, must copy to Auto_beam_engraver too */
  
@@ -240,6 +240,11 @@ Beam_engraver::acknowledge_grob (Grob_info info)
        }
       else if (Stem::has_interface (info.elem_l_))
        {
+         Moment now = now_mom();
+
+         if(bool (now.grace_mom_ ) != bool (beam_start_mom_.grace_mom_))
+           return ;
+         
          Item *stem_l = dynamic_cast<Item*> (info.elem_l_);
          if (Stem::beam_l (stem_l))
            return;
@@ -270,7 +275,7 @@ Beam_engraver::acknowledge_grob (Grob_info info)
 
          stem_l->set_grob_property ("duration-log",
                                    gh_int2scm (durlog));
-         Moment stem_location = now_mom () - beam_start_mom_ + beam_start_location_;
+         Moment stem_location = now - beam_start_mom_ + beam_start_location_;
          beam_info_p_->add_stem (stem_location,
  (durlog- 2) >? 1);
          Beam::add_stem (beam_p_, stem_l);
index 019765c883388790b185e7d1057680bb58ff6866..b045401a028d3fac6a21de30d72aefe824a8bbb0 100644 (file)
 #define SPACING_SPANNER_HH
 
 #include "spanner.hh"
+#include "spring.hh"
 
 class Spacing_spanner
 {
 public:
   static void set_interface (Grob*);
-  static void do_measure (Grob*,Link_array<Grob>) ;
-
+  static void do_measure (Grob*,Link_array<Grob> const &) ;
+  static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Grob> const &);
   DECLARE_SCHEME_CALLBACK (set_springs, (SCM ));
   static Real stem_dir_correction (Grob*,Grob*,Grob*)  ;
   static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment)  ;
index 9585c874dda65941ab2e1a044e2857778ba17cf9..236841bcb0f7ca081149aeb3c54b5c0f606e32ba 100644 (file)
@@ -34,6 +34,7 @@ struct Spring{
   */
   Real strength_f_;
   void add_to_cols ();
+  void set_to_cols ();
   Spring ();
 };
 
index c87f51ed7f226298f7528d8af356faff8aead0ce..b66cd6b490ce5fbe56b2a0925d36ac3ad2b15c0d 100644 (file)
@@ -82,6 +82,17 @@ Key_item::brew_molecule (SCM smob)
 
   Real inter = Staff_symbol_referencer::staff_space (me)/2.0;
   
+  SCM scm_style = me->get_grob_property ("style");
+  String style;
+  if (gh_symbol_p (scm_style))
+    {
+      style = ly_scm2string (scm_symbol_to_string (scm_style));
+    }
+  else
+    {
+      style = "";
+    }
+
   SCM newas = me->get_grob_property ("new-accidentals");  
   Molecule mol;
   /*
@@ -89,13 +100,15 @@ Key_item::brew_molecule (SCM smob)
     the cancellation signature.
   */
   int c0p = gh_scm2int (me->get_grob_property ("c0-position"));
+
   for (SCM s = newas; gh_pair_p (s); s = gh_cdr (s))
     {
       SCM what = gh_caar (s);
       int alter = gh_scm2int (gh_cdar (s));
       int pos = alteration_pos (what, alter, c0p);
       
-      Molecule m = Font_interface::get_default_font (me)->find_by_name ("accidentals-" + to_str (alter));
+      Molecule m = Font_interface::get_default_font (me)->
+         find_by_name (String ("accidentals-") + style + to_str (alter));
       m.translate_axis (pos * inter, Y_AXIS);
       mol.add_at_edge (X_AXIS, LEFT, m, 0);
     }
@@ -117,7 +130,8 @@ Key_item::brew_molecule (SCM smob)
 
       Molecule natural;
       if (gh_pair_p (old))
-       natural=Font_interface::get_default_font (me)->find_by_name ("accidentals-0");
+       natural=Font_interface::get_default_font (me)->
+           find_by_name (String ("accidentals-") + style + String ("0"));
       
       for (; gh_pair_p (old); old = gh_cdr (old))
         {
index bc49391582238c96b5d4a01379266d0672bdbf04..fe7d9de2abb404ee0b6b0a25db8dad714d987855 100644 (file)
@@ -126,6 +126,20 @@ Local_key_item::brew_molecule (SCM smob)
   bool oct_b = false;
   int lastoct = -100;
 
+  SCM scm_style = me->get_grob_property ("style");
+  String style;
+  if (gh_symbol_p (scm_style))
+    {
+      style = ly_scm2string (scm_symbol_to_string (scm_style));
+    }
+  else
+    {
+      /*
+       preferably no name for the default style.
+       */
+      style = "";
+    }
+
   SCM accs = me->get_grob_property ("accidentals");
   for (SCM s = accs;
        gh_pair_p (s); s = gh_cdr (s))
@@ -154,13 +168,16 @@ Local_key_item::brew_molecule (SCM smob)
       SCM c0 =  me->get_grob_property ("c0-position");
       Real dy = (gh_number_p (c0) ? gh_scm2int (c0) : 0 + p.notename_i_)
        * note_distance;
-      
-      Molecule acc (Font_interface::get_default_font (me)->find_by_name (String ("accidentals-")
-                                              + to_str (p.alteration_i_)));
+
+      Molecule acc (Font_interface::get_default_font (me)->
+                   find_by_name (String ("accidentals-") +
+                                 style +
+                                 to_str (p.alteration_i_)));
       
       if (scm_memq (ly_symbol2scm ("natural"), opts) != SCM_BOOL_F)
        {
-         Molecule prefix = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-0"));
+         Molecule prefix = Font_interface::get_default_font (me)->
+             find_by_name (String ("accidentals-") + style + String ("0"));
          acc.add_at_edge (X_AXIS, LEFT, Molecule (prefix), 0);
        }
 
diff --git a/lily/regular-spacing-engraver.cc b/lily/regular-spacing-engraver.cc
new file mode 100644 (file)
index 0000000..e6cb130
--- /dev/null
@@ -0,0 +1,60 @@
+/*   
+  regular-spacing-engraver.cc --  implement Regular_spacing_engraver
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "engraver.hh"
+#include "grob.hh"
+
+class Regular_spacing_engraver : public Engraver
+{
+public:
+  Regular_spacing_engraver ();
+  VIRTUAL_COPY_CONS(Translator);
+
+  Moment last_moment_;
+  SCM last_col_;
+protected:
+  virtual void process_music ();
+};
+
+Regular_spacing_engraver::Regular_spacing_engraver ()
+{
+  last_col_ = SCM_EOL;
+}
+
+void
+Regular_spacing_engraver::process_music ()
+{
+  SCM delta = get_property ("regularSpacingDelta");
+
+  if (unsmob_moment (delta))
+    {
+      SCM mp = get_property ("measurePosition");
+      if (!unsmob_moment (mp))
+       return;
+
+      Rational d = unsmob_moment (delta)->main_part_;
+      Rational p = unsmob_moment (mp)->main_part_;
+
+      if (p.mod_rat (d) != Rational (0))
+       return;
+
+      Moment now = now_mom ();
+      SCM col = get_property ("currentMusicalColumn");
+      if (p
+         && (now -last_moment_ ).main_part_ == d)
+       {
+         unsmob_grob (col)->set_grob_property ("regular-distance-to", last_col_);
+       }
+      last_col_ = col;
+      last_moment_ = now;
+    }
+}
+
+
+ADD_THIS_TRANSLATOR(Regular_spacing_engraver);
index 1bff342744f9b8205f725f61857074a99d161fe9..497f4c934b65318635b9e4ae9f7fd4e3ca23d753 100644 (file)
@@ -104,7 +104,7 @@ find_runs (Grob*me, Link_array<Grob> cols)
   
  */
 void
-Spacing_spanner::do_measure (Grob*me, Link_array<Grob> cols) 
+Spacing_spanner::do_measure (Grob*me, Link_array<Grob> const & cols) 
 {
   Moment shortest;
   Moment mean_shortest;
@@ -140,6 +140,7 @@ Spacing_spanner::do_measure (Grob*me, Link_array<Grob> cols)
     }
   mean_shortest /= n;
 
+  Array<Spring> springs;
   for (int i= 0; i < cols.size () - 1; i++)
     {
       Item * l = dynamic_cast<Item*> (cols[i]);
@@ -265,10 +266,134 @@ Spacing_spanner::do_measure (Grob*me, Link_array<Grob> cols)
          else
            s.strength_f_ /= stretch_dist;
          
-         s.add_to_cols ();
+         springs.push (s);
        }
     }
+
+  Spacing_spanner::stretch_to_regularity (me, &springs, cols);
+  for (int i=springs.size (); i --;)
+    springs[i].add_to_cols ();
+}
+
+/*
+  Look at COLS, searching for columns that have 'regular-distance-to
+  set. A sequence of columns that have this property set should have
+  an equal distance (an equispaced run). Extract the projected
+  distance from SPRINGS, and scale SPRINGS for the equispaced run, to the
+  widest space necessary.
+
+
+  TODO:
+  
+  -- inefficient code; maybe it is easier to twiddle with the springs
+  after they've become grob properties (ie. have their
+  minimum-distances set)
+
+  -- does not adjust strength field of the springs very well: result
+  awkward spacing at the start of a line. (?)
+
+  -- will be confused when there are multiple equispaced runs in a measure.
+
+  -- dealing with springs for line breaks is a little tricky; in any
+  case, we will only space per measure.
+
+  -- we scale to actual distances, not to optical effects. Eg. if the
+  equispaced run contains optical corrections, then the scaling will
+  cancel those.
+
+  -- Regular_spacing_engraver doesn't mark the first column of the
+  next bar, making the space before a barline too short, in this case
+
+
+       x<- 16ths--> x(8th)
+       x(8th)       x(8th)      <- equispaced run.      
+  
+*/
+
+void
+Spacing_spanner::stretch_to_regularity (Grob *me,
+                                       Array<Spring> * springs,
+                                       Link_array<Grob> const & cols)
+{
+  /*
+    Find the starting column of the run. REGULAR-DISTANCE-TO points
+    back to a previous column, so we look ahead to find a column
+    pointing back to the first one.
+    
+   */
+  Grob    * first_regular_spaced_col = 0;
+  for (int i = 0 ;  i <  cols.size () && !first_regular_spaced_col; i++)
+    {
+      SCM rdt = cols[i]->get_grob_property ("regular-distance-to");
+      if (cols.find_l (unsmob_grob (rdt)))
+       first_regular_spaced_col = unsmob_grob (rdt);
+    }
+  for (int i = springs->size ();  i-- ;)
+    springs->elem (i).set_to_cols ();
+  
+  int i;
+  for (i = 0; i < springs->size ()
+        && springs->elem (i).item_l_drul_[RIGHT] != first_regular_spaced_col;
+       i++)
+    ;
+
+
+  if (i==springs->size ())
+    return ;
+    
+  Real maxdist = 0.0;
+  Real dist  =0.0;
+  Grob *last_col = first_regular_spaced_col;
+  Grob *last_regular_spaced_col = first_regular_spaced_col;
   
+
+  /*
+    find the max distance for this run. 
+   */
+  for (int j = i;  j < springs->size (); j++)
+    {
+      Spring *s = &(springs->elem_ref (j));
+      if (s->item_l_drul_[LEFT] != last_col)
+       continue;
+      
+      dist += s->distance_f_;
+
+      last_col = s->item_l_drul_[RIGHT];
+      SCM rdt = last_col->get_grob_property ("regular-distance-to");
+      if (unsmob_grob (rdt) == last_regular_spaced_col)
+       {
+         maxdist = maxdist >? dist;
+         dist = 0.0;
+         last_regular_spaced_col = last_col;
+       }
+
+    }
+
+  /*
+    Scale the springs
+   */
+  dist =0.0;
+  last_col =  first_regular_spaced_col;
+  last_regular_spaced_col = first_regular_spaced_col;
+  for (int j = i;   j < springs->size (); j++)
+    {
+      Spring *s = &springs->elem_ref (j);
+      if (s->item_l_drul_[LEFT] != last_col)
+       continue;
+      dist += s->distance_f_;
+
+      last_col = s->item_l_drul_[RIGHT];
+      SCM rdt = last_col->get_grob_property ("regular-distance-to");
+      if (unsmob_grob (rdt) == last_regular_spaced_col)
+       {
+         do {
+           springs->elem_ref (i).distance_f_ *= maxdist / dist;
+           springs->elem_ref (i).strength_f_ *= dist / maxdist;            
+         } while (i++ < j);
+         last_regular_spaced_col = last_col;
+         dist =0.0;
+       }
+    }
 }
 
 /**
index 93ef33f59ef0327cfe0a2e687d80b6bd12c6b992..e63fee0891b0d1fab26bc63031b9015dd89b1721 100644 (file)
@@ -20,6 +20,11 @@ Spring::Spring ()
   strength_f_ =1.0;
 }
 
+/*
+
+ ugh : if we go from items to cols, we should adjust distance and strength.
+ */
+
 void
 Spring::add_to_cols ()
 {
@@ -28,6 +33,17 @@ Spring::add_to_cols ()
                                 distance_f_, strength_f_);
 }
 
+void
+Spring::set_to_cols( )
+{
+  Direction d = LEFT;
+  do
+    {
+      item_l_drul_[d] = item_l_drul_[d]->column_l ();
+    }
+  while (flip (&d) != LEFT);
+
+}
 
 Column_spring::Column_spring ()
 {
index a3e14ce4833708d9a8cbc45e2ead04821ec6761a..1227a9315bc25bbdbd0880f7b7e05dd59d891306 100644 (file)
@@ -59,7 +59,8 @@ Volta_engraver::process_music ()
     {
       SCM c = gh_car (cs);
 
-      if (gh_pair_p (c) && gh_car (c) == ly_symbol2scm ("volta"))
+      if (gh_pair_p (c) && gh_car (c) == ly_symbol2scm ("volta")
+         && gh_pair_p (gh_cdr (c)))
        {
          if (gh_cadr (c) ==  SCM_BOOL_F)
            end = true;
index f4d8f310950ef2165f98b8f38d9605551eead86a..59caa945c286c14f980a52ede99c4ee8c81fb8d7 100644 (file)
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.5.2
-Entered-date: 15JUL01
+Version: 1.5.3
+Entered-date: 29JUL01
 Description: @BLURB@
 Keywords: music notation typesetting midi fonts engraving
 Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
        janneke@gnu.org (Jan Nieuwenhuizen)
 Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
 Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
-       1000k lilypond-1.5.2.tar.gz 
+       1000k lilypond-1.5.3.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-       1000k lilypond-1.5.2.tar.gz 
+       1000k lilypond-1.5.3.tar.gz 
 Copying-policy: GPL
 End
index f8843949cadacc4a2b00ad39b59bde3b35910656..d703e0339fad1ed7bc3964b00014e0b1e1b8009d 100644 (file)
@@ -1,11 +1,11 @@
 %define info yes
 
 Name: lilypond
-Version: 1.5.2
+Version: 1.5.3
 Release: 1
 License: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.2.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.3.tar.gz
 Summary: Create and print music notation 
 URL: http://www.cs.uu.nl/~hanwen/lilypond
 BuildRoot: /tmp/lilypond-install
index 4b7115682ebd6f20f81e255ae946f3b0acea8539..4ee22f615fef45b830e5851811ebb8eb9cf6cb76 100644 (file)
 
 Distribution: SuSE Linux 7.0 (i386)
 Name: lilypond
-Version: 1.5.2
+Version: 1.5.3
 Release: 2
 Copyright:    GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.2.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.3.tar.gz
 # music notation software for.. ?
 Summary: A program for printing sheet music.
 URL: http://www.lilypond.org/
index 8e46d414278a2c354f3f8c024a2663ccd188b60c..6ad17211d68d77a884645ba3ab4329f65241bbde 100644 (file)
@@ -583,7 +583,7 @@ def draw_brevis(expr exact_center, reduction, small_width, small_height) =
 enddef;
 
 
-def draw_mensural_i_c_clef(expr exact_center, reduction) = 
+def draw_neo_mensural_c_clef(expr exact_center, reduction) = 
        draw_brevis(exact_center, reduction, false, false);
 
        save reduced_il, reduced_slt;
@@ -618,18 +618,20 @@ def draw_mensural_i_c_clef(expr exact_center, reduction) =
 enddef;
 
 
-fet_beginchar("mensural c clef", "mensural1_c", "mens1cclef")
+fet_beginchar("neo-mensural c clef", "neo_mensural_c", "neomenscclef")
        if test = 1:
                draw_staff(-1,3, 0.0);
        fi;
-       draw_mensural_i_c_clef((0,0), 1.0);
+       draw_neo_mensural_c_clef((0,0), 1.0);
 fet_endchar;
-fet_beginchar("mensural c clef", "mensural1_c_change", "cmens1cclef")
-       draw_mensural_i_c_clef((1.3 staff_space#,0), .8);
+fet_beginchar("neo-mensural c clef", "neo_mensural_c_change", "cneomenscclef")
+       draw_neo_mensural_c_clef((1.3 staff_space#,0), .8);
 fet_endchar;
 
 
-def draw_mensural_ii_c_clef(expr exact_center, reduction) = 
+def draw_petrucci_c_clef(expr exact_center, reduction) = 
+       % inspired by Josquin Desprez, "Stabat Mater", Libro tertio,
+       % 1519, printed by Petrucci, in: MGG, volume 7, Table 11.
        draw_brevis(exact_center, reduction, true, true);
 
        save reduced_il, reduced_slt;
@@ -645,39 +647,47 @@ def draw_mensural_ii_c_clef(expr exact_center, reduction) =
        define_pixels(stem_width);
        define_pixels(interline);
 
+       addto currentpicture also currentpicture
+               yscaled -1 shifted (0, 2*(ypart exact_center) - interline);
+
        penpos6(stem_width, 0);
        penpos7(stem_width, 0);
-       z6l = exact_center + (0, -interline/2);
-       z7l = z6l + (0, -1.5reduced_il);
+       z6l = exact_center + (0, 0);
+       z7l = z6l + (0, -2.2reduced_il);
        fill z6l -- z7l -- z7r -- z6r -- cycle;
 
-       addto currentpicture also currentpicture
-               yscaled -1 shifted (0, 2*(ypart exact_center) - interline);
-       addto currentpicture also currentpicture
-               yscaled -1 shifted (0, 4*(ypart exact_center));
        addto currentpicture also currentpicture 
                xscaled -1 shifted (2x4l,0);
 
+       penpos8(stem_width, 0);
+       penpos9(stem_width, 0);
+       z8l = exact_center + (0, 0);
+       z9l = z8l + (0, -3.2reduced_il);
+       fill z8l -- z9l -- z9r -- z8r -- cycle;
+
+       addto currentpicture also currentpicture
+               yscaled -1 shifted (0, 4*(ypart exact_center));
+
        set_char_box(0, 2head_width#,
                     noteheight#*4*reduction, noteheight#*4*reduction);
 enddef;
 
 
-fet_beginchar("mensural c clef", "mensural2_c", "mens2cclef")
+fet_beginchar("petrucci c clef", "petrucci_c", "petruccicclef")
        if test = 1:
                draw_staff(-1,3, 0.0);
        fi;
-       draw_mensural_ii_c_clef((0,0), 1.0);
+       draw_petrucci_c_clef((0,0), 1.0);
 fet_endchar;
-fet_beginchar("mensural c clef", "mensural2_c_change", "cmens2cclef")
-       draw_mensural_ii_c_clef((1.3 staff_space#,0), .8);
+fet_beginchar("petrucci c clef", "petrucci_c_change", "cpetruccicclef")
+       draw_petrucci_c_clef((1.3 staff_space#,0), .8);
 fet_endchar;
 
 
-def draw_mensural_iii_c_clef(expr exact_center, reduction) =
+def draw_mensural_c_clef(expr exact_center, reduction) =
        % inspired by Ockeghem, "Missa Prolationum", in: MGG, volume
        % 9, table 94.
-       draw_mensural_ii_c_clef(exact_center, reduction);
+       draw_petrucci_c_clef(exact_center, reduction);
 
        addto currentpicture also currentpicture
                shifted (0, -interline);
@@ -687,14 +697,14 @@ def draw_mensural_iii_c_clef(expr exact_center, reduction) =
 enddef;
 
 
-fet_beginchar("mensural c clef", "mensural3_c", "mens3cclef")
+fet_beginchar("mensural c clef", "mensural_c", "menscclef")
        if test = 1:
                draw_staff(-1,3, 0.0);
        fi;
-       draw_mensural_iii_c_clef((0,0), 1.0);
+       draw_mensural_c_clef((0,0), 1.0);
 fet_endchar;
-fet_beginchar("mensural c clef", "mensural3_c_change", "cmens3cclef")
-       draw_mensural_iii_c_clef((0,0), .8);
+fet_beginchar("mensural c clef", "mensural_c_change", "cmenscclef")
+       draw_mensural_c_clef((0,0), .8);
 fet_endchar;
 
 def draw_diamond(expr exact_center, reduction) =
@@ -728,12 +738,13 @@ def draw_diamond(expr exact_center, reduction) =
                cycle;
 enddef;
 
-def draw_mensural_i_f_clef(expr exact_center, reduction) =
-       %
+def draw_petrucci_f_clef(expr exact_center, reduction) =
+       % inspired by L'homme arme super voces musicales in Misse
+       % Josquin, 1502, Petrucci, in: MGG, volume 7, col. 200; also
        % inspired by Gaspar van Weerbeke, "Virgo Maria" (1502), in:
-       % MGG, volume 9, col. 653 ("Motette"), fig. 3.; also by
-       % Andr'e Campra, "Entr'ee des s'er'enades" (1710), in: MGG,
-       % volume 2, col. 1649 ("Contredanse"), fig. 2.
+       % MGG, volume 9, col. 653 ("Motette"), fig. 3.; also by Andr'e
+       % Campra, "Entr'ee des s'er'enades" (1710), in: MGG, volume 2,
+       % col. 1649 ("Contredanse"), fig. 2.
        %
        draw_brevis(exact_center, reduction, true, false);
 
@@ -763,12 +774,13 @@ def draw_mensural_i_f_clef(expr exact_center, reduction) =
 
        draw_diamond(exact_center +
                     (1.6interline*reduction, interline/2), reduction);
-       %% some editions put a stem on top of the upper note head:
-       % penpos8(stem_width, 0);
-       % penpos9(stem_width, 0);
-       % z8l = exact_center + (1.6interline*reduction, interline*reduction);
-       % z9l = z8l + (0, 1.5interline*reduction);
-       % fill z8l -- z9l -- z9r -- z8r -- cycle;
+
+       % upper stem
+       penpos8(stem_width, 0);
+       penpos9(stem_width, 0);
+       z8l = exact_center + (1.6interline*reduction, interline*reduction);
+       z9l = z8l + (0, 1.5interline*reduction);
+       fill z8l -- z9l -- z9r -- z8r -- cycle;
 
        draw_diamond(exact_center +
                     (1.6interline*reduction, -interline/2), reduction);
@@ -783,18 +795,18 @@ def draw_mensural_i_f_clef(expr exact_center, reduction) =
 enddef;
 
 
-fet_beginchar("mensural f clef", "mensural1_f", "mens1fclef")
+fet_beginchar("petrucci f clef", "petrucci_f", "petruccifclef")
        if test = 1:
                draw_staff(-1,3, 0.0);
        fi;
-       draw_mensural_i_f_clef((0,0), 1.0);
+       draw_petrucci_f_clef((0,0), 1.0);
 fet_endchar;
-fet_beginchar("mensural f clef", "mensural1_f_change", "cmens1fclef")
-       draw_mensural_i_f_clef((0,0), .8);
+fet_beginchar("petrucci f clef", "petrucci_f_change", "cpetruccifclef")
+       draw_petrucci_f_clef((0,0), .8);
 fet_endchar;
 
 
-def draw_mensural_ii_f_clef(expr exact_center, reduction) =
+def draw_mensural_f_clef(expr exact_center, reduction) =
        %
        % inspired by Philippe le Duc, "Dite Signori" (1590), in: MGG,
        % volume 3, col. 848 ("Duc"); also by John Dowland, "The First
@@ -830,14 +842,14 @@ def draw_mensural_ii_f_clef(expr exact_center, reduction) =
        set_char_box(0, 3staff_space#, 3staff_space#, 0);
 enddef;
 
-fet_beginchar("mensural f clef", "mensural2_f", "mens2fclef")
+fet_beginchar("mensural f clef", "mensural_f", "mensfclef")
        if test = 1:
                draw_staff(-1,3, 0.0);
        fi;
-       draw_mensural_ii_f_clef((0,0), 1.0);
+       draw_mensural_f_clef((0,0), 1.0);
 fet_endchar;
-fet_beginchar("mensural f clef", "mensural2_f_change", "cmens2fclef")
-       draw_mensural_ii_f_clef((0,0), .8);
+fet_beginchar("mensural f clef", "mensural_f_change", "cmensfclef")
+       draw_mensural_f_clef((0,0), .8);
 fet_endchar;
 
 
@@ -935,6 +947,71 @@ fet_endchar;
 
 
 
+def draw_petrucci_g_clef(expr exact_center, reduction) =
+       % inspired by Josquin Desprez, "Stabat Mater", Libro tertio,
+       % 1519, printed by Petrucci, in: MGG, volume 7, Table 11.
+
+       set_char_box(0.6 staff_space#, 0.8 staff_space#, 0.6 staff_space#, 
+         4.0 staff_space#);
+
+       save reduced_il, reduced_slt;
+
+       reduced_il# = staff_space# * reduction;
+       reduced_slt# = stafflinethickness# * reduction;
+       define_pixels(reduced_il, reduced_slt);
+
+       save za, zb, zc, zd, ze, zf, zg, zh, zi, zj;
+       pair za, zb, zc, zd, ze, zf, zg, zh, zi, zj;
+
+       pickup pencircle
+               xscaled 0.50 reduced_slt
+               yscaled 0.22 reduced_il
+               rotated -35;
+
+       za = exact_center + (+0.00 reduced_il, +0.00 reduced_il);
+       zb = exact_center + (+0.20 reduced_il, +1.20 reduced_il);
+       zc = exact_center + (-0.10 reduced_il, +2.00 reduced_il);
+       zd = exact_center + (-0.50 reduced_il, +3.00 reduced_il);
+       ze = exact_center + (+0.00 reduced_il, +3.70 reduced_il);
+       zf = exact_center + (+0.20 reduced_il, +3.00 reduced_il);
+       zg = exact_center + (-0.20 reduced_il, +2.00 reduced_il);
+       zh = exact_center + (-0.50 reduced_il, +1.70 reduced_il);
+       zi = exact_center + (-0.80 reduced_il, +0.75 reduced_il);
+       zj = exact_center + (-0.60 reduced_il, +0.60 reduced_il);
+
+       draw za{-1,2} .. zb .. zc .. zd .. ze .. zf .. zg .. zh .. zi .. zj;
+
+       save za, zb, zc, zd, ze, zf;
+       pair za, zb, zc, zd, ze, zf;
+
+       pickup pencircle
+               xscaled 0.75 reduced_slt
+               yscaled 0.33 reduced_il
+               rotated -35;
+
+       za = exact_center + (+0.25 reduced_il, +0.45 reduced_il);
+       zb = exact_center + (-0.25 reduced_il, +0.45 reduced_il);
+       zc = exact_center + (-0.25 reduced_il, -0.45 reduced_il);
+       zd = exact_center + (+0.25 reduced_il, -0.45 reduced_il);
+       ze = exact_center + (+0.30 reduced_il, +0.00 reduced_il);
+       zf = exact_center + (+0.00 reduced_il, +0.00 reduced_il);
+
+       draw za .. zb .. zc .. zd .. {up}ze -- zf;
+enddef;
+
+
+fet_beginchar("petrucci g clef", "petrucci_g", "petruccigclef")
+       if test = 1:
+               draw_staff(-1,3, 0.0);
+       fi;
+       draw_petrucci_g_clef((0,0), 1.0);
+fet_endchar;
+fet_beginchar("petrucci g clef", "petrucci_g_change", "cpetruccigclef")
+       draw_petrucci_g_clef((0,0), .8);
+fet_endchar;
+
+
+
 %%%%%%%%
 %
 %
index ad008adc34cbd585da421b1915e40cdb2134051d..21bacb30446566025ec64a5094e1f36c6914f499 100644 (file)
@@ -26,7 +26,7 @@ fet_begingroup("accidentals");
 % a square pen).  [Wanske] does not mention this, so we'll just ignore 
 % this fact
 %
-fet_beginchar("Sharp" , "1", "sharp");
+fet_beginchar("Default Sharp" , "1", "sharp");
        set_char_box(0, 1.1 staff_space#, 1.5 staff_space#, 
                1.5 staff_space#);
 
@@ -82,7 +82,7 @@ fet_beginchar("Sharp" , "1", "sharp");
        labels(1,2,3,4);
        fet_endchar;
 
-fet_beginchar( "Natural", "0", "natural")
+fet_beginchar( "Default Natural", "0", "natural")
        set_char_box(0, 8/12 staff_space#, 1.5 staff_space#, 1.5 staff_space#);
 
        save interbeam, interstem, beamheight, beamwidth, 
@@ -203,13 +203,13 @@ enddef;
 %
 % unfortunately, 600dpi is not enough to show the brush of the stem.
 %
-fet_beginchar("Flat", "-1", "flat")
+fet_beginchar("Default Flat", "-1", "flat")
        set_char_box(1.2 stafflinethickness#, .8 staff_space#, .5 staff_space#, 2 staff_space#);
        draw_meta_flat(0, w, 1/3 staff_space);
        fet_endchar;
 
 
-fet_beginchar("Double flat", "-2", "flatflat")
+fet_beginchar("Default Double Flat", "-2", "flatflat")
        save left_wid, overlap, right_wid;
        left_wid = .7;
        right_wid = .8;
@@ -220,7 +220,7 @@ fet_beginchar("Double flat", "-2", "flatflat")
                right_wid *staff_space, 1/3 staff_space);
        fet_endchar;
 
-fet_beginchar("Double sharp", "2", "sharpsharp")
+fet_beginchar("Default Double Sharp", "2", "sharpsharp")
        set_char_box(0, staff_space#, .5 staff_space#, .5 staff_space#);
        save klaverblad, klaversteel;
 
@@ -270,16 +270,179 @@ def draw_paren =
        .. simple_serif(z1r, z1l, 90) .. z2l{down} -- cycle;
 enddef;
   
-fet_beginchar("Right parenthesis", ")", "rightparen")
+fet_beginchar("Right Parenthesis", ")", "rightparen")
        draw_paren;
 fet_endchar;
 
-fet_beginchar("Left parenthesis", "(", "leftparen")
+fet_beginchar("Left Parenthesis", "(", "leftparen")
        draw_paren;
         currentpicture := currentpicture xscaled -1;
         set_char_box(charwd, charbp, chardp, charht);
 fet_endchar;
 
+%%%%%%%%
+%
+%
+%
+% EDITIO MEDICAEA
+%
+%
+%
+fet_beginchar("Ed. Med. Flat" , "medicaea-1", "medicaeaflat");
+       set_char_box(0, 0.8 staff_space#, 0.6 staff_space#, 
+         2.0 staff_space#);
+
+       pickup pencircle
+               xscaled 0.50 stafflinethickness
+               yscaled 0.22 staff_space;
+
+       save za, zb;
+       pair za, zb;
+
+       za = (0.00 staff_space, +0.90 staff_space);
+       zb = (0.00 staff_space, -0.50 staff_space);
+       draw za -- zb;
+
+       pickup pencircle
+               xscaled 0.50 stafflinethickness
+               yscaled 0.22 staff_space
+               rotated -63;
+
+       save zc, zd, ze;
+       pair zc, zd, ze;
+
+       zc = (0.10 staff_space, -0.50 staff_space);
+       zd = (0.40 staff_space, +0.40 staff_space);
+       ze = (0.10 staff_space, +0.40 staff_space);
+
+       draw zc{(1,2)} .. zd .. ze{(-1,-1)};
+
+       fet_endchar;
+
+%%%%%%%%
+%
+%
+%
+% EDITIO VATICANA
+%
+%
+%
+fet_beginchar("Ed. Vat. Flat" , "vaticana-1", "vaticanaflat");
+        set_char_box(0, 0.8 staff_space#, 0.6 staff_space#, 
+                2.0 staff_space#);
+        define_pixels (stafflinethickness, staff_space);
+
+        save za, zb, zc, zd, ze, zf, zg;
+        pair za, zb, zc, zd, ze, zf, zg;
+        za = (0.00 staff_space, +0.80 staff_space);
+        zb = (0.00 staff_space, -0.03 staff_space);
+        zc = (0.25 staff_space, -0.23 staff_space);
+        zd = (0.50 staff_space, -0.23 staff_space);
+        ze = (0.50 staff_space, +0.00 staff_space);
+        zf = (0.25 staff_space, +0.20 staff_space);
+        zg = (0.15 staff_space, +0.26 staff_space);
+
+        pickup pencircle
+                xscaled 0.50 stafflinethickness
+                yscaled 0.22 staff_space;
+        draw za{down} .. {down}zb .. zc .. zd{up} .. {up}ze .. zf .. zg;
+        fet_endchar;
+
+fet_beginchar("Ed. Vat. Natural" , "vaticana0", "vaticananatural");
+       set_char_box(0, 0.7 staff_space#, 0.6 staff_space#, 
+               2.0 staff_space#);
+       define_pixels (stafflinethickness, staff_space);
+
+       save za, zb, zc, zd;
+       pair za, zb, zc, zd;
+       pickup pencircle
+               xscaled 0.80 stafflinethickness
+               yscaled 0.22 staff_space;
+       za = (0.00 staff_space, +0.65 staff_space);
+       zb = (0.00 staff_space, -0.35 staff_space);
+       zc = (0.00 staff_space, -0.30 staff_space);
+       zd = (0.40 staff_space, -0.08 staff_space);
+       draw za -- zb;
+       draw zc -- zd;
+
+       addto currentpicture also currentpicture
+               xscaled -1
+               yscaled -1
+               shifted (0.40 staff_space, 0.0 staff_space);
+
+       fet_endchar;
+
+%%%%%%%%
+%
+%
+%
+% MENSURAL NOTATION
+%
+%
+%
+fet_beginchar("Mensural Sharp" , "mensural1", "mensuralsharp");
+       set_char_box(0, 0.7 staff_space#, 0.5 staff_space#, 
+               0.5 staff_space#);
+       save stemthick;
+       define_pixels (stemthick, staff_space);
+       stemthick# = stafflinethickness#;
+
+       save za, zb;
+       pair za, zb;
+       pickup pencircle scaled 0.8 stemthick;
+       za = 0.4 * staff_space * (0.8, 1);
+       za = -zb;
+       draw za .. zb;
+
+       addto currentpicture also currentpicture xscaled -1;
+       addto currentpicture also currentpicture shifted (0.20 staff_space, 0);
+
+       fet_endchar;
+
+fet_beginchar("Mensural Flat" , "mensural-1", "mensuralflat");
+       set_char_box(0, 0.7 staff_space#, 0.4 staff_space#, 
+               1.8 staff_space#);
+       save stemthick;
+       define_pixels (stemthick, staff_space);
+       stemthick# = stafflinethickness#;
+
+       save za, zb, zc, zd, ze;
+       pair za, zb, zc, zd, ze;
+       pickup pencircle
+               xscaled 1.4 stemthick
+               yscaled 0.6 stemthick
+               rotated 45;
+
+       za = (0.00 staff_space, +1.80 staff_space);
+       zb = (0.00 staff_space, -0.25 staff_space);
+       zc = (0.35 staff_space, -0.25 staff_space);
+       zd = (0.35 staff_space, +0.25 staff_space);
+       ze = (0.00 staff_space, +0.25 staff_space);
+       draw za -- zb .. zc .. zd .. ze;
+       fet_endchar;
+
+fet_beginchar("Hufnagel Flat" , "hufnagel-1", "hufnagelflat");
+       set_char_box(0, 0.7 staff_space#, 0.4 staff_space#, 
+               1.8 staff_space#);
+       save stemthick;
+       define_pixels (stemthick, staff_space);
+       stemthick# = stafflinethickness#;
+
+       save za, zb, zc, zd, ze, zf;
+       pair za, zb, zc, zd, ze, zf;
+       pickup pencircle
+               xscaled 2.4 stemthick
+               yscaled 0.4 stemthick
+               rotated 45;
+
+       za = (0.00 staff_space, +1.80 staff_space);
+       zb = (0.00 staff_space, -0.15 staff_space);
+       zc = (0.25 staff_space, -0.30 staff_space);
+       zd = (0.50 staff_space, +0.00 staff_space);
+       ze = (0.30 staff_space, +0.30 staff_space);
+       zf = (0.00 staff_space, +0.15 staff_space);
+       draw za -- zb -- zc .. zd .. ze -- zf;
+       fet_endchar;
 
 fet_endgroup("accidentals");
 
index e76878cf5fdf6926904efa7b32e08bcadc4e7a42..7f02a51e5dcdffaf73e07cca64f037f1e9746ba0 100644 (file)
@@ -25,6 +25,7 @@
 (define (default-break-barline glyph dir)
    (let ((result (assoc glyph 
                        '((":|:" . (":|" . "|:"))
+                         ("||:" . ("||" . "|:"))
                          ("|" . ("|" . ""))
                          ("|s" . (nil . "|"))
                          ("|:" . ("|" . "|:"))
index a6f11bd692de919ac1db0597d8756ee0f032e350..e4203218f6f1500b0069bf5f2ab6543a0ce45edb 100644 (file)
          ("hufnagel_fa1" . ("clefs-hufnagel_fa" -1 0))
          ("hufnagel_fa2" . ("clefs-hufnagel_fa" 1 0))
          ("hufnagel_do_fa" . ("clefs-hufnagel_do_fa" 4 0))
-         ("mensural1_c1" . ("clefs-mensural1_c" -4 0))
-         ("mensural1_c2" . ("clefs-mensural1_c" -2 0))
-         ("mensural1_c3" . ("clefs-mensural1_c" 0 0))
-         ("mensural1_c4" . ("clefs-mensural1_c" 2 0))
-         ("mensural2_c1" . ("clefs-mensural2_c" -4 0))
-         ("mensural2_c2" . ("clefs-mensural2_c" -2 0))
-         ("mensural2_c3" . ("clefs-mensural2_c" 0 0))
-         ("mensural2_c4" . ("clefs-mensural2_c" 2 0))
-         ("mensural2_c5" . ("clefs-mensural2_c" 4 0))
-         ("mensural3_c1" . ("clefs-mensural3_c" -2 0))
-         ("mensural3_c2" . ("clefs-mensural3_c" 0 0))
-         ("mensural3_c3" . ("clefs-mensural3_c" 2 0))
-         ("mensural3_c4" . ("clefs-mensural3_c" 4 0))
-         ("mensural1_f" . ("clefs-mensural1_f" 2 0))
-         ("mensural2_f" . ("clefs-mensural2_f" 2 0))
+         ("mensural_c1" . ("clefs-mensural_c" -2 0))
+         ("mensural_c2" . ("clefs-mensural_c" 0 0))
+         ("mensural_c3" . ("clefs-mensural_c" 2 0))
+         ("mensural_c4" . ("clefs-mensural_c" 4 0))
+         ("mensural_f" . ("clefs-mensural_f" 2 0))
          ("mensural_g" . ("clefs-mensural_g" -2 0))
+         ("neo_mensural_c1" . ("clefs-neo_mensural_c" -4 0))
+         ("neo_mensural_c2" . ("clefs-neo_mensural_c" -2 0))
+         ("neo_mensural_c3" . ("clefs-neo_mensural_c" 0 0))
+         ("neo_mensural_c4" . ("clefs-neo_mensural_c" 2 0))
+         ("petrucci_c1" . ("clefs-petrucci_c" -4 0))
+         ("petrucci_c2" . ("clefs-petrucci_c" -2 0))
+         ("petrucci_c3" . ("clefs-petrucci_c" 0 0))
+         ("petrucci_c4" . ("clefs-petrucci_c" 2 0))
+         ("petrucci_c5" . ("clefs-petrucci_c" 4 0))
+         ("petrucci_f" . ("clefs-petrucci_f" 2 0))
+         ("petrucci_g" . ("clefs-petrucci_g" -2 0))
        )
 )
 
     ("clefs-hufnagel_do" . 0)
     ("clefs-hufnagel_fa" . 4)
     ("clefs-hufnagel_do_fa" . 0)
-    ("clefs-mensural1_c" . 0)
-    ("clefs-mensural2_c" . 0)
-    ("clefs-mensural3_c" . 0)
-    ("clefs-mensural1_f" . 4)
-    ("clefs-mensural2_f" . 4)
-    ("clefs-mensural_g" . -4))
+    ("clefs-mensural_c" . 0)
+    ("clefs-mensural_f" . 4)
+    ("clefs-mensural_g" . -4)
+    ("clefs-neo_mensural_c" . 0)
+    ("clefs-petrucci_c" . 0)
+    ("clefs-petrucci_f" . 4)
+    ("clefs-petrucci_g" . -4)
   )
+)
 
 (define (clef-name-to-properties cl)
   (let ((e '())
diff --git a/scm/foo.scm b/scm/foo.scm
deleted file mode 100644 (file)
index e69de29..0000000
index 1511bf2a964905f10d1e780c0122271ac9ba31ed..1c9487df19505691e25596816b0ab2a2b09b04b7 100644 (file)
@@ -13,7 +13,7 @@
 #  * articulation
 #  * grace notes
 #  * tuplets
-
+#
 
 # todo:
 #  * slur/stem directions
@@ -22,9 +22,9 @@
 #  * beams (better use autobeam?)
 #  * more robust: try entertainer.etf (freenote)
 #  * dynamics
-#  * automatic `deletion' of invalid items
+#  * empty measures (eg. twopt03.etf from freenote)
 #
-
+# 
 
 program_name = 'etf2ly'
 version = '@TOPLEVEL_VERSION@'
@@ -225,16 +225,16 @@ class Tuplet:
                        sys.stderr.write ("\nHuh? Tuplet starting at entry %d was too short." % self.start_note)
                
 class Slur:
-       def __init__ (self, number):
+       def __init__ (self, number, params):
                self.number = number
-               self.finale = []
+               self.finale = params
 
        def append_entry (self, finale_e):
                self.finale.append (finale_e)
 
        def calculate (self, chords):
-               startnote = self.finale[0][5]
-               endnote = self.finale[3][2]
+               startnote = self.finale[5]
+               endnote = self.finale[3*6 + 2]
                try:
                        cs = chords[startnote]
                        ce = chords[endnote]
@@ -254,7 +254,9 @@ class Global_measure:
                self.number = number
                self.keysignature = None
                self.scale = None
-
+               self.force_break = 0
+               
+               self.repeats = []
                self.finale = []
 
        def __str__ (self):
@@ -274,32 +276,60 @@ class Global_measure:
                self.keysignature = k
                self.scale = find_scale (k)
 
+       def set_flags (self,flag1, flag2):
+               
+               # flag1 isn't all that interesting.
+               if flag2 & 0x8000:
+                       self.force_break = 1
+                       
+               if flag2 & 0x0008:
+                       self.repeats.append ('start')
+               if flag2 & 0x0004:
+                       self.repeats.append ('stop')
+                       
+               if flag2 & 0x0002:
+                       if flag2 & 0x0004:
+                               self.repeats.append ('bracket')
 
 articulation_dict ={
-       11: '\\prall',
-       12: '\\mordent',
-       8: '\\fermata',
-       4: '^',
-       1: '.',
-       3: '>',
-       18: '"arp"' , # arpeggio
+       94: '^',
+       109: '\\prall',
+       84: '\\turn',
+       62: '\\mordent',
+       85: '\\fermata',
+       46: '.',
+#      3: '>',
+#      18: '\arpeggio' ,
 }
 
+class Articulation_def:
+       def __init__ (self, n, a, b):
+               self.finale_glyph = a & 0xff
+               self.number = n
+
+       def dump (self):
+               try:
+                       return articulation_dict[self.finale_glyph]
+               except KeyError:
+                       sys.stderr.write ("\nUnknown articulation no. %d" % self.finale_glyph)
+                       sys.stderr.write ("\nPlease add an entry to articulation_dict in the Python source")                    
+                       return None
+       
 class Articulation:
        def __init__ (self, a,b, finale):
-               self.type = finale[0]
+               self.definition = finale[0]
                self.notenumber = b
-       def calculate (self, chords):
+               
+       def calculate (self, chords, defs):
                c = chords[self.notenumber]
 
-               try:
-                       a = articulation_dict[self.type]
-               except KeyError:
-                       sys.stderr.write ("\nUnknown articulation no. %d on note no. %d" % (self.type, self.notenumber))
-                       sys.stderr.write ("\nPlease add an entry to articulation_dict in the Python source")
-                       a = '"art"'
-                       
-               c.note_suffix = '-' + a + c.note_suffix
+               adef = defs[self.definition]
+               lystr =adef.dump()
+               if lystr == None:
+                       lystr = '"art"'
+                       sys.stderr.write ("\nThis happened on note %d" % self.notenumber)
+
+               c.note_suffix = '-' + lystr
 
 class Syllable:
        def __init__ (self, a,b , finale):
@@ -355,8 +385,6 @@ class Measure:
                self.staff = None
                self.valid = 1
                
-       def add_finale_entry (self, entry):
-               self.finale.append (entry)
 
        def valid (self):
                return self.valid
@@ -365,13 +393,11 @@ class Measure:
 
                if len (self.finale) < 2:
                        fs = self.finale[0]
-                       fs = map (string.atoi, list (fs))
+
                        self.clef = fs[1]
                        self.frames = [fs[0]]
                else:
-                       fs = self.finale[0] + self.finale[1]
-                       
-                       fs = map (string.atoi, list (fs))
+                       fs = self.finale
                        self.clef = fs[0]
                        self.flags = fs[1]
                        self.frames = fs[2:]
@@ -438,15 +464,13 @@ class Staff:
                self.measures = []
 
        def get_measure (self, no):
-               if len (self.measures) <= no:
-                       self.measures = self.measures + [None]* (1 + no - len (self.measures))
+               fill_list_to (self.measures, no)
 
                if self.measures[no] == None:
                        m = Measure (no)
                        self.measures [no] =m
                        m.staff = self
 
-
                return self.measures[no]
        def staffid (self):
                return 'staff' + encodeint (self.number - 1)
@@ -465,13 +489,35 @@ class Staff:
                        
                        g = m.global_measure
                        e = ''
-                       if g and last_key <> g.keysignature:
-                               e = e + "\\key %s \\major " % lily_notename (g.keysignature)
-                               last_key = g.keysignature
-                       if g and last_time <> g.timesig :
-                               e = e + "\\time %d/%d " % g.timesig
-                               last_time = g.timesig
+                       
+                       if g:
+                               if last_key <> g.keysignature:
+                                       e = e + "\\key %s \\major " % lily_notename (g.keysignature)
+                                       last_key = g.keysignature
+                               if last_time <> g.timesig :
+                                       e = e + "\\time %d/%d " % g.timesig
+                                       last_time = g.timesig
+
+                               if 'start' in g.repeats:
+                                       e = e + ' \\bar "|:" ' 
+
 
+                               # we don't attempt voltas since they fail easily.
+                               if 0 : # and g.repeat_bar == '|:' or g.repeat_bar == ':|:' or g.bracket:
+                                       strs = []
+                                       if g.repeat_bar == '|:' or g.repeat_bar == ':|:' or g.bracket == 'end':
+                                               strs.append ('#f')
+
+                                       
+                                       if g.bracket == 'start':
+                                               strs.append ('"0."')
+
+                                       str = string.join (map (lambda x: '(volta %s)' % x, strs))
+                                       
+                                       e = e + ' \\property Score.repeatCommands =  #\'(%s) ' % str
+
+                               if g.force_break:
+                                       e = e + ' \\break '  
                        
                        if last_clef <> m.clef :
                                e = e + '\\clef "%s"' % lily_clef (m.clef)
@@ -484,7 +530,8 @@ class Staff:
                                
                        if g:
                                gap = rat_add (gap, g.length ())
-
+                               if 'stop' in g.repeats:
+                                       k = k + ' \\bar ":|" '
                                
                k = '%sglobal = \\notes  { %s }\n\n ' % (self.staffid (), k)
                return k
@@ -501,17 +548,15 @@ class Staff:
                        gap = (0,1)
                        for m in self.measures[1:]:
                                if not m or not m.valid:
-                                       sys.stderr.write ("Skipping non-existant measure")
+                                       sys.stderr.write ("Skipping non-existant or invalid measure\n")
                                        continue
 
                                fr = None
                                try:
                                        fr = m.frames[x]
                                except IndexError:
-                                       
-                                       sys.stderr.write ("Skipping nonexistent frame")
-                                       laystr = laystr + "% FOOBAR ! \n"
-                                       print laystr
+                                       sys.stderr.write ("Skipping nonexistent frame %d\n" % x)
+                                       laystr = laystr + "%% non existent frame %d (skipped) \n" % x
                                if fr:
                                        first_frame = fr
                                        if gap <> (0,1):
@@ -543,15 +588,24 @@ class Staff:
 
                                
 
+def ziplist (l):
+       if len (l) < 2:
+               return []
+       else:
+               return [(l[0], l[1])] + ziplist (l[2:])
+
 
 class Chord:
-       def __init__ (self, finale_entry):
+       def __init__ (self, number, contents):
                self.pitches = []
                self.frame = None
-               self.finale = finale_entry
+               self.finale = contents[:7]
+
+               self.notelist = ziplist (contents[7:])
                self.duration  = None
                self.next = None
                self.prev = None
+               self.number = number
                self.note_prefix= ''
                self.note_suffix = ''
                self.chord_suffix = ''
@@ -579,37 +633,37 @@ class Chord:
                        mylen = rat_multiply (mylen, self.tuplet.factor())
                return mylen
                
-       def number (self):
-               return self.finale[0][0]
 
        def EDU_duration (self):
-               return self.finale[0][3]
+               return self.finale[2]
        def set_duration (self):
                self.duration = EDU_to_duration(self.EDU_duration ())
+               
        def calculate (self):
                self.find_realpitch ()
                self.set_duration ()
 
-               flag = self.finale[0][5]
+               flag = self.finale[4]
                if Chord.GRACE_MASK & flag:
                        self.grace = 1
                
-               
+       
        def find_realpitch (self):
-               
-               ((no, prev, next, dur, pos, entryflag, extended, follow), notelist) = self.finale
 
                meas = self.measure ()
                tiestart = 0
                if not meas or not meas.global_measure  :
-                       print 'note %d not in measure' % self.number ()
+                       sys.stderr.write ('note %d not in measure\n' % self.number)
                elif not meas.global_measure.scale:
-                       print  'note %d: no scale in this measure.' % self.number ()
+                       sys.stderr.write ('note %d: no scale in this measure.' % self.number)
                else:
-                       for p in notelist:
+                       
+                       for p in self.notelist:
                                (pitch, flag) = p
-                               
+
+
                                nib1 = pitch & 0x0f
+                               
                                if nib1 > 8:
                                        nib1 = -(nib1 - 8)
                                rest = pitch / 16
@@ -632,7 +686,8 @@ class Chord:
 
                rest = ''
 
-               if not (self.finale[0][5] & Chord.REST_MASK):
+
+               if not (self.finale[4] & Chord.REST_MASK):
                        rest = 'r'
                
                for p in self.pitches:
@@ -664,40 +719,137 @@ class Chord:
                s = self.chord_prefix + s + self.chord_suffix
                return s
 
-GFre = re.compile(r"""^\^GF\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
-BCre = re.compile (r"""^\^BC\(([0-9-]+)\) ([0-9-]+) .*$""")
-eEre = re.compile(r"""^\^eE\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) \$([0-9A-Fa-f]+) ([0-9-]+) ([0-9-]+)""")
-FRre = re.compile (r"""^\^FR\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
-MSre = re.compile (r"""^\^MS\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
-note_re = re.compile (r"""^ +([0-9-]+) \$([A-Fa-f0-9]+)""")
-Sxre  = re.compile (r"""^\^Sx\(([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
-IMre = re.compile (r"""^\^IM\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
-vere = re.compile(r"""^\^(ve|ch|se)\(([0-9-]+),([0-9-]+)\) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
-versere = re.compile(r"""^\^verse\(([0-9]+)\)(.*)\^end""")
 
-TPre = re.compile(r"""^\^TP\(([0-9]+),([0-9]+)\) *([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+)""")
+def fill_list_to (list, no):
+       """
+Add None to LIST until it contains entry number NO.
+       """
+       while len (list) <= no:
+               list.extend ([None] * (no - len(list) + 1))
+       return list
+
+def read_finale_value (str):
+       while str and str[0] in ' \t\n':
+               str = str[1:]
+
+       if not str:
+               return (None,str)
+       
+       if str[0] == '$':
+               str = str [1:]
+
+               hex = ''
+               while str and str[0] in '0123456789ABCDEF':
+                       hex = hex  + str[0]
+                       str = str[1:]
+
+               
+               return (string.atol (hex, 16), str)
+       elif str[0] == '"':
+               str = str[1:]
+               s = ''
+               while str and str[0] <> '"':
+                       s = s + str[0]
+                       str = str[1:]
+
+               return (s,str)
+       elif str[0] in '-0123456789':
+               dec = ''
+               while str and str[0] in '-0123456789':
+                       dec = dec  + str[0]
+                       str = str[1:]
+                       
+               return (string.atoi (dec), str)
+       else:
+               sys.stderr.write ("Can't convert `%s'\n" % str)
+               return (None, str)
+
+
+
+       
+def parse_etf_file (fn, tag_dict):
+
+       """ Read FN, putting ETF info into
+       a giant dictionary.  The keys of TAG_DICT indicate which tags
+       to put into the dict.
+       """
+       
+       sys.stderr.write ('parsing ... ' )
+       f = open (fn)
+       
+       gulp = re.sub ('[\n\r]+', '\n',  f.read ())
+       ls = string.split (gulp, '\n^')
+
+       etf_file_dict = {}
+       for k in tag_dict.keys (): 
+               etf_file_dict[k] = {}
+
+       last_tag = None
+       last_numbers = None
+
+
+       for l in  ls:
+               m = re.match ('^([a-zA-Z0-9&]+)\(([^)]+)\)', l)
+               if m and tag_dict.has_key (m.group (1)):
+                       tag = m.group (1)
+
+                       indices = tuple (map (string.atoi, string.split (m.group (2), ',')))
+                       content = l[m.end (2)+1:]
+
+
+                       tdict = etf_file_dict[tag]
+                       if not tdict.has_key (indices):
+                               tdict[indices] = []
+
+
+                       parsed = []
+
+                       if tag == 'verse' or tag == 'block':
+                               m2 = re.match ('(.*)\^end', content)
+                               if m2:
+                                       parsed = [m2.group (1)]
+                       else:
+                               while content:
+                                       (v, content) = read_finale_value (content)
+                                       if v <> None:
+                                               parsed.append (v)
+
+                       tdict [indices].extend (parsed)
+
+                       last_indices = indices
+                       last_tag = tag
+
+                       continue
+
+# let's not do this: this really confuses when eE happens to be before  a ^text.
+#              if last_tag and last_indices:
+#                      etf_file_dict[last_tag][last_indices].append (l)
+                       
+       sys.stderr.write ('\n') 
+       return etf_file_dict
+
+       
+
 
 
 class Etf_file:
        def __init__ (self, name):
                self.measures = [None]
-               self.entries = [None]
                self.chords = [None]
                self.frames = [None]
                self.tuplets = [None]
                self.staffs = [None]
-               self.slur_dict = {}
+               self.slurs = [None]
                self.articulations = [None]
                self.syllables = [None]
                self.verses = [None]
-               
+               self.articulation_defs = [None]
+
                ## do it
                self.parse (name)
 
        def get_global_measure (self, no):
-               if len (self.measures) <= no:
-                       self.measures = self.measures + [None]* (1 + no - len (self.measures))
-
+               fill_list_to (self.measures, no)
                if self.measures[no] == None:
                        self.measures [no] = Global_measure (no)
 
@@ -705,178 +857,124 @@ class Etf_file:
 
                
        def get_staff(self,staffno):
-               if len (self.staffs) <= staffno:
-                       self.staffs = self.staffs + [None] * (1 + staffno - len (self.staffs))
-
+               fill_list_to (self.staffs, staffno)
                if self.staffs[staffno] == None:
                        self.staffs[staffno] = Staff (staffno)
 
                return self.staffs[staffno]
 
        # staff-spec
-       def try_IS (self, l):
+       def try_IS (self, indices, contents):
                pass
 
-       def try_BC (self, l):
-               m =  BCre.match  (l)
-               if m:
-                       bn = string.atoi (m.group (1))
-                       where = string.atoi (m.group (2)) / 1024.0
-               return m
-       def try_TP(self, l):
-               m = TPre.match (l)
-               if m:
-                       (nil, num) = map (string.atoi, (m.groups ()[0:2]))
-                       entries = map (string.atoi, (m.groups ()[2:]))
-
-                       if self.tuplets[-1] == None or num <> self.tuplets[-1].start_note:
-                               self.tuplets.append (Tuplet (num))
-
-                       self.tuplets[-1].append_finale (entries)
-                       
-       def try_IM (self, l):
-               m = IMre.match (l)
-               if m:
-                       a = string.atoi (m.group (1))
-                       b = string.atoi (m.group (2))
-
-                       fin = map (string.atoi, m.groups ()[2:])
-
-                       self.articulations.append (Articulation (a,b,fin))
-               return m
-       def try_verse (self,l):
-               m =  versere .match (l)
-               if m:
-                       a = string.atoi (m.group (1))
-                       body =m.group (2)
-
-                       body = re.sub (r"""\^[a-z]+\([^)]+\)""", "", body)
-                       body = re.sub ("\^[a-z]+", "", body)
-                       self.verses.append (Verse (a, body))
-                       
-               return m
-       def try_ve (self,l):
-               m = vere .match (l)
-               if m:
-                       a = string.atoi (m.group (1))
-                       b = string.atoi (m.group (2))
-
-                       fin = map (string.atoi, m.groups ()[2:])
-
-                       self.syllables.append (Syllable (a,b,fin))
-               return m
-       def try_eE (self, l):
-               m = eEre.match (l)
-               if m:
-                       tup = m.groups()
-                       (no, prev, next, dur, pos, entryflag, extended, follow) = tup
-                       (no, prev, next, dur, pos,extended, follow) \
-                         = tuple (map (string.atoi, [no,prev,next,dur,pos,extended,follow]))
-
-                       entryflag = string.atol (entryflag,16)
-                       if len (self.entries) <= no:
-                               # missing entries seem to be quite common.
-                               # we fill'em up with None.
-                               self.entries = self.entries + [None] * (no - len (self.entries) + 1)
-                                       
-                       current_entry = ((no, prev, next, dur, pos, entryflag, extended, follow), [])
-                       self.entries[no] = current_entry
-               return m
-
-       def try_Sx(self,l):
-               m = Sxre.match (l)
-               if m:
-                       slurno = string.atoi (m.group (1))
-
-                       sl = None
-                       try:
-                               sl = self.slur_dict[slurno]
-                       except KeyError:
-                               sl = Slur (slurno)
-                               self.slur_dict[slurno] = sl
-
-                       params = list (m.groups ()[1:])
-                       params = map (string.atoi, params)
-                       sl.append_entry (params)
-
-               return m        
-       def try_GF(self, l):
-               m = GFre.match (l)
-               if m:
-                       (staffno,measno) = m.groups ()[0:2]
-                       s = string.atoi (staffno)
-                       me = string.atoi (measno)
-                       
-                       entry = m.groups () [2:]
-                       st = self.get_staff (s)
-                       meas = st.get_measure (me)
-                       meas.add_finale_entry (entry)
-               
-       # frame  ?
-       def try_FR(self, l):
-               m = FRre.match (l)
-               if m:
-                       (frameno, startnote, endnote, foo, bar) = m.groups ()
-                       (frameno, startnote, endnote)  = tuple (map (string.atoi, [frameno, startnote, endnote]))
-                       if len (self.frames) <= frameno:
-                               self.frames = self.frames + [None]  * (frameno - len(self.frames) + 1)
-                       
-                       self.frames[frameno] = Frame ((frameno, startnote, endnote))
-                       
-               return m
-       
-       def try_MS (self, l):
-               m = MSre.match (l)
-               if m:
-                       measno = string.atoi (m.group (1))
-                       keynum = string.atoi (m.group (3))
-                       meas =self. get_global_measure (measno)
-                       meas.set_keysig (keynum)
-
-                       beats = string.atoi (m.group (4))
-                       beatlen = string.atoi (m.group (5))
-                       meas.set_timesig ((beats, beatlen))
-                                               
-               return m
-
-       def try_note (self, l):
-               m = note_re.match (l)
-               if m:
-                       (pitch, flag) = m.groups ()
-                       pitch = string.atoi (pitch)
-                       flag = string.atol (flag,16)
-                       self.entries[-1][1].append ((pitch,flag))
-
-       def parse (self, name):
-               sys.stderr.write ('parsing ...')
-               sys.stderr.flush ()
+       def try_BC (self, indices, contents):
+               bn = indices[0]
+               where = contents[0] / 1024.0
+       def try_TP(self,  indices, contents):
+               (nil, num) = indices
+
+               if self.tuplets[-1] == None or num <> self.tuplets[-1].start_note:
+                       self.tuplets.append (Tuplet (num))
+
+               self.tuplets[-1].append_finale (contents)
+
+       def try_IM (self, indices, contents):
+               (a,b) = indices
+               fin = contents
+               self.articulations.append (Articulation (a,b,fin))
+       def try_verse (self, indices, contents):
+               a = indices[0]
+               body = contents[0]
+
+               body = re.sub (r"""\^[a-z]+\([^)]+\)""", "", body)
+               body = re.sub ("\^[a-z]+", "", body)
+               self.verses.append (Verse (a, body))
+       def try_ve (self,indices, contents):
+               (a,b) = indices
+               self.syllables.append (Syllable (a,b,contents))
+
+       def try_eE (self,indices, contents):
+               no = indices[0]
+               (prev, next, dur, pos, entryflag, extended, follow) = contents[:7]
+
+               fill_list_to (self.chords, no)
+               self.chords[no]  =Chord (no, contents)
+
+       def try_Sx(self,indices, contents):
+               slurno = indices[0]
+               fill_list_to (self.slurs, slurno)
+               self.slurs[slurno] = Slur(slurno, contents)
+
+       def try_IX (self, indices, contents):
+               n = indices[0]
+               a = contents[0]
+               b = contents[1]
+
+               ix= None
+               try:
+                       ix = self.articulation_defs[n]
+               except IndexError:
+                       ix = Articulation_def (n,a,b)
+                       self.articulation_defs.append (Articulation_def (n, a, b))
 
-               gulp = open (name).read ()
+       def try_GF(self, indices, contents):
+               (staffno,measno) = indices
 
-               gulp = re.sub ('[\n\r]+', '\n',  gulp)
-               ls = string.split (gulp, '\n')
+               st = self.get_staff (staffno)
+               meas = st.get_measure (measno)
+               meas.finale = contents
+               
+       def try_FR(self, indices, contents):
+               frameno = indices [0]
                
-               for l in ls:
-                       m = None
-                       if not m: 
-                               m = self.try_MS (l)
-                       if not m: 
-                               m = self.try_FR (l)
-                       if not m: 
-                               m = self.try_GF (l)
-                       if not m: 
-                               m = self.try_note (l)
-                       if not m: 
-                               m = self.try_eE (l)
-                       if not m:
-                               m = self.try_IM (l)
-                       if not m:
-                               m = self.try_Sx (l)
-                       if not m:
-                               m = self.try_TP (l)
-                       if not m:
-                               m = self.try_verse (l)
+               startnote = contents[0]
+               endnote = contents[1]
+
+               fill_list_to (self.frames, frameno)
+       
+               self.frames[frameno] = Frame ((frameno, startnote, endnote))
+       
+       def try_MS (self, indices, contents):
+               measno = indices[0]
+               keynum = contents[1]
+               meas =self. get_global_measure (measno)
+               meas.set_keysig (keynum)
+
+               beats = contents[2]
+               beatlen = contents[3]
+               meas.set_timesig ((beats, beatlen))
+
+               meas_flag1 = contents[4]
+               meas_flag2 = contents[5]
+
+               meas.set_flags (meas_flag1, meas_flag2);
+
+
+       routine_dict = {
+               'MS': try_MS,
+               'FR': try_FR,
+               'GF': try_GF,
+               'IX': try_IX,
+               'Sx' : try_Sx,
+               'eE' : try_eE,
+               'verse' : try_verse,
+               've' : try_ve,
+               'IM' : try_IM,
+               'TP' : try_TP,
+               'BC' : try_BC,
+               'IS' : try_IS,
+               }
+       
+       def parse (self, etf_dict):
+               sys.stderr.write ('reconstructing ...')
+               sys.stderr.flush ()
 
+               for (tag,routine) in Etf_file.routine_dict.items ():
+                       ks = etf_dict[tag].keys ()
+                       ks.sort ()
+                       for k in ks:
+                               routine (self, k, etf_dict[tag][k])
+                       
                sys.stderr.write ('processing ...')
                sys.stderr.flush ()
 
@@ -925,10 +1023,12 @@ class Etf_file:
                for t in self.tuplets[1:]:
                        t.calculate (self.chords)
                        
-               for s in self.slur_dict.values():
-                       s.calculate (self.chords)
+               for s in self.slurs[1:]:
+                       if s:
+                               s.calculate (self.chords)
+                       
                for s in self.articulations[1:]:
-                       s.calculate (self.chords)
+                       s.calculate (self.chords, self.articulation_defs)
                        
        def get_thread (self, startno, endno):
 
@@ -942,7 +1042,7 @@ class Etf_file:
                        return []
 
                
-               while c and c.number () <> endno:
+               while c and c.number <> endno:
                        thread.append (c)
                        c = c.next
 
@@ -978,24 +1078,18 @@ class Etf_file:
                return 'ETF FILE %s %s' % (self.measures,  self.entries)
        
        def unthread_entries (self):
-               self.chords = [None]
-               for e in self.entries[1:]:
-                       ch = None
-                       if e:           
-                               ch = Chord (e)
-                       self.chords.append (ch)
-                               
                for e in self.chords[1:]:
                        if not e:
                                continue
-                       e.prev = self.chords[e.finale[0][1]]
-                       e.next = self.chords[e.finale[0][2]]
+
+                       e.prev = self.chords[e.finale[0]]
+                       e.next = self.chords[e.finale[1]]
 
 def identify():
        sys.stderr.write ("%s from LilyPond %s\n" % (program_name, version))
 
 def help ():
-       print """Usage: etf2ly [OPTION]... ETF-FILE
+       sys.stdout.write("""Usage: etf2ly [OPTION]... ETF-FILE
 
 Convert ETF to LilyPond.
 
@@ -1011,17 +1105,17 @@ ready-to-use lilypond file.
 Report bugs to bug-gnu-music@gnu.org
 
 Written by  Han-Wen Nienhuys <hanwen@cs.uu.nl>
-"""
+""")
 
 def print_version ():
-       print r"""etf2ly (GNU lilypond) %s
+       sys.stdout.write (r"""etf2ly (GNU lilypond) %s
 
 This is free software.  It is covered by the GNU General Public License,
 and you are welcome to change it and/or distribute copies of it under
 certain conditions.  Invoke as `midi2ly --warranty' for more information.
 
 Copyright (c) 2000 by Han-Wen Nienhuys <hanwen@cs.uu.nl>
-""" % version
+""" % version)
 
 
 
@@ -1052,7 +1146,9 @@ for f in files:
                f = ''
 
        sys.stderr.write ('Processing `%s\'\n' % f)
-       e = Etf_file(f)
+
+       dict = parse_etf_file (f, Etf_file.routine_dict)
+       e = Etf_file(dict)
        if not out_filename:
                out_filename = os.path.basename (re.sub ('(?i).etf$', '.ly', f))