]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.82
authorfred <fred>
Tue, 26 Mar 2002 23:55:06 +0000 (23:55 +0000)
committerfred <fred>
Tue, 26 Mar 2002 23:55:06 +0000 (23:55 +0000)
51 files changed:
Documentation/ntweb/guile-1.4-gnu-windows.patch [new file with mode: 0644]
aclocal.m4
buildscripts/pmx2ly.py [new file with mode: 0644]
input/bugs/slur-steep-broken.ly [new file with mode: 0644]
input/test/pushproperty.ly
input/trip.ly
lily/audio-element-info.cc
lily/auto-change-iterator.cc
lily/axis-group-interface.cc
lily/bar-engraver.cc
lily/bar-number-engraver.cc
lily/break-align-engraver.cc
lily/change-iterator.cc
lily/clef-engraver.cc
lily/engraver-group-engraver.cc
lily/grace-engraver-group.cc
lily/grace-performer-group.cc
lily/identifier.cc
lily/include/audio-element-info.hh
lily/include/grace-engraver-group.hh
lily/include/grace-performer-group.hh
lily/include/identifier.hh
lily/include/lyric-phrasing-engraver.hh
lily/include/translation-property.hh
lily/include/translator-group.hh
lily/include/translator.hh
lily/key-engraver.cc
lily/lexer.ll
lily/lyric-phrasing-engraver.cc
lily/mark-engraver.cc
lily/music-output-def.cc
lily/parser.yy
lily/part-combine-music-iterator.cc
lily/performer-group-performer.cc
lily/performer.cc
lily/piano-pedal-engraver.cc
lily/property-engraver.cc
lily/property-iterator.cc
lily/repeat-engraver.cc
lily/score-element.cc
lily/score-performer.cc
lily/score.cc
lily/syllable-group.cc [new file with mode: 0644]
lily/translator-group.cc
lily/translator.cc
lily/voice-devnull-engraver.cc
scm/chord-names.scm
scm/generic-property.scm
scm/lily.scm
scripts/abc2ly.py
stepmake/aclocal.m4

diff --git a/Documentation/ntweb/guile-1.4-gnu-windows.patch b/Documentation/ntweb/guile-1.4-gnu-windows.patch
new file mode 100644 (file)
index 0000000..4dd55d3
--- /dev/null
@@ -0,0 +1,85 @@
+diff -urN ../guile-1.4/ChangeLog ./ChangeLog
+--- ../guile-1.4/ChangeLog     Fri Jun  2 15:17:01 2000
++++ ./ChangeLog        Mon Jun  5 15:18:32 2000
+@@ -1,3 +1,12 @@
++2000-06-05    <janneke@gnu.org>
++ 
++      * guile-config/cross-guile-config.in: Simple shell script to
++      take over guile-config's functionality for cross-compilation.
++      It will be installed as ${target}-guile-config.
++ 
++      * guile-config/Makefile.am: Provide for cross-guile-config.in
++      and its targets.
++ 
+ 2000-06-21  Mikael Djurfeldt  <mdj@thalamus.nada.kth.se>
+       * Guile 1.4 released.
+diff -urN ../guile-1.4/configure.in ./configure.in
+--- ../guile-1.4/configure.in  Fri Jun  2 08:44:27 2000
++++ ./configure.in     Mon Jun  5 15:13:58 2000
+@@ -21,6 +21,7 @@
+ dnl  Boston, MA 02111-1307, USA.
+ AC_INIT(Makefile.in)
++AC_CANONICAL_SYSTEM
+ . $srcdir/GUILE-VERSION
+ AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
+ AM_MAINTAINER_MODE
+diff -urN ../guile-1.4/guile-config/Makefile.am ./guile-config/Makefile.am
+--- ../guile-1.4/guile-config/Makefile.am      Wed Jan 12 22:42:41 2000
++++ ./guile-config/Makefile.am Mon Jun  5 15:17:37 2000
+@@ -20,9 +20,9 @@
+ ##   to the Free Software Foundation, Inc., 59 Temple Place, Suite
+ ##   330, Boston, MA 02111-1307 USA
+-bin_SCRIPTS=guile-config
+-CLEANFILES=guile-config
+-EXTRA_DIST=guile-config.in guile.m4
++bin_SCRIPTS=guile-config @target@-guile-config
++CLEANFILES=guile-config @target@-guile-config
++EXTRA_DIST=guile-config.in guile.m4 cross-guile-config.in
+ ## FIXME: in the future there will be direct automake support for
+ ## doing this.  When that happens, switch over.
+@@ -39,6 +39,21 @@
+           -e s:@-GUILE_VERSION-@:${GUILE_VERSION}:
+       chmod +x guile-config.tmp
+       mv guile-config.tmp guile-config
++
++LDFLAGS=@LDFLAGS@
++CFLAGS=@CFLAGS@
++CPPFLAGS=@CPPFLAGS@
++ 
++@target@-guile-config: cross-guile-config.in
++      rm -f $<.tmp
++      sed < ${srcdir}/$< > $<.tmp \
++          -e s:@-SHELL-@:${SHELL}: \
++          -e s:@-GUILE_VERSION-@:${GUILE_VERSION}:\
++          -e s:@-PREFIX-@:${prefix}: \
++          -e "s:@-CPPFLAGS-@:${CPPFLAGS}:" \
++          -e "s:@-LDFLAGS-@:${LDFLAGS}:"
++      chmod +x $<.tmp
++      mv $<.tmp $@
+ ## Get rid of any copies of the configuration script under the old
+ ## name, so people don't end up running ancient copies of it.
+diff -urN ../guile-1.4/guile-config/cross-guile-config.in ./guile-config/cross-guile-config.in
+--- ../guile-1.4/guile-config/cross-guile-config.in    Thu Jan  1 01:00:00 1970
++++ ./guile-config/cross-guile-config.in       Mon Jun  5 15:13:58 2000
+@@ -0,0 +1,16 @@
++#!@-SHELL-@
++# target-guile-config.in
++case $1 in
++      --version)
++              echo "@-GUILE_VERSION-@"
++              exit 0
++              ;;
++      compile)
++              echo "@-CPPFLAGS-@ -I @-PREFIX-@/include/guile"
++              exit 0
++              ;;
++      link)
++              echo "-L @-PREFIX-@/lib -lguile @-LDFLAGS-@"
++              exit 0
++              ;;
++esac
index 122038c7f77b83270523f7a46a12682904d3df5c..d1220794a6556252cd1e021bd4316df0149ef426 100644 (file)
@@ -648,20 +648,24 @@ AC_DEFUN(AC_STEPMAKE_TEXMF, [
            break;
        fi
     done
+    AC_MSG_RESULT($MFMODE)
 
+    AC_MSG_CHECKING(for mfplain.mp)
     #
     # For now let people define these in their environments
     #
     : ${MFPLAIN_MP=`kpsewhich mp mfplain.mp`}
+    AC_MSG_RESULT($MFPLAIN_MP)
 
+    AC_MSG_CHECKING(for inimetapost flags)
     if test  ${INIMETAPOST} = "inimp" ; then
        : ${INIMETAPOST_FLAGS=''}
     else
        : ${INIMETAPOST_FLAGS='-interaction=nonstopmode'}
     fi
+    AC_MSG_RESULT($INIMETAPOST_FLAGS)
 
     rm -f mfput.*
-    AC_MSG_RESULT($MFMODE)
 
     AC_SUBST(METAFONT)
     AC_SUBST(METAPOST)
diff --git a/buildscripts/pmx2ly.py b/buildscripts/pmx2ly.py
new file mode 100644 (file)
index 0000000..58d32cb
--- /dev/null
@@ -0,0 +1,25 @@
+#!@PYTHON@
+import string
+
+ls = open ('barsant.pmx').readlines ()
+def stripcomment (l):
+       return re.sub ('^%.*$', '', l)
+       
+ls = map (stripcomment, ls)
+ls = filter (lambda x: x <> '', ls)
+
+opening = ls[0]
+ls = ls[1:]
+
+opening = map (string.atoi, re.split ('[\t ]+', opening))
+(nv,noinst,mtrnuml,mtrdenl,mtrnump,mtrdenp,xmtrnum0,isig) = tuple (opening)
+
+
+opening = ls[0]
+ls = ls[1:]
+opening = map (string.atoi, re.split ('[\t ]+', opening))
+(npages,nsyst,musicsize,fracindent) = tuple (opening)
+
+for l  in ls:
+       pass
+       
diff --git a/input/bugs/slur-steep-broken.ly b/input/bugs/slur-steep-broken.ly
new file mode 100644 (file)
index 0000000..f5f495e
--- /dev/null
@@ -0,0 +1,9 @@
+\score{
+  \notes\relative c''{
+    \time 2/4;
+    [f8 e d f, (] | \break
+    [) a'8. gis16 fis8. cis16] |
+  }
+  \paper{linewidth = 3.0\cm;indent = .0;}
+}
+
index 7ca018f9b96ecb48a6b878ea21d05be926d03991..0ab097c1a345368c26f8d80195c2a53da80b354a 100644 (file)
@@ -49,10 +49,6 @@ Incorrect (\popproperty costs memory):
        \popproperty #'(  ... ) #'symbolA 
        \popproperty #'(  ... ) #'symbolB 
 
-
-
-
-
 the syntax isn't likely to stay, so it is advisable to
 use identifiers, eg.
 
@@ -64,15 +60,21 @@ use identifiers, eg.
 
 \score { \notes
 \relative c' {
-       c4(
+       c4-.(
        \context Voice \pushproperty #'(basicDotsProperties basicStemProperties
        basicNoteColumnProperties basicScriptProperties basicTextProperties) #'direction #-1
-       ) c4 (
-       ) c4 (  
-       \context Voice \pushproperty #'(basicSlurProperties) #'direction #-1
-       ) c4 ( \context Voice  \popproperty #'(basicDotsProperties basicStemProperties
+       ) c4-. (
+       ) c4-. (        
+       \context Voice \pushproperty #'basicSlurProperties #'direction #-1
+       ) c4-. ( \context Voice  \popproperty #'(basicDotsProperties basicStemProperties
                basicScriptProperties basicTextProperties) #'direction
 
-        ) c4  () c4 
+        ) c4-.  () c4-. 
+}
+
+\paper {
+\translator { \VoiceContext
+       \pushproperty #'basicNoteHeadProperties #'font-size #-2
+}
 }
 }
index 750a0f6eb73cbef1fd3247cc9617aea32c595f3a..ed3e877acdf544cbab247394f4fff577e60b3dcd 100644 (file)
@@ -15,6 +15,8 @@ TODO:
 
 * tremolo
 
+* lyrics.
+
 %}
 
 \version "1.3.59";
index 5580b6f0b897f870575b7f6d9f751ca664a5d7e5..c9f99c77323f2a36be3f04540e24e398d524b337 100644 (file)
@@ -7,11 +7,12 @@
 */
 
 #include "audio-element-info.hh"
-#include "request.hh"
+#include "translator-group.hh"
 
 Audio_element_info::Audio_element_info (Audio_element*s_l, Music *r_l)
 {
   elem_l_ = s_l;
+  origin_trans_l_ =0;
   req_l_ = r_l;
 }
 
@@ -20,10 +21,19 @@ Audio_element_info::Audio_element_info()
 {
   elem_l_ = 0;
   req_l_ = 0;
+  origin_trans_l_ =0;
 }
 
+
 Link_array<Translator>
-Audio_element_info::origin_trans_l_arr (Translator*) const
+Audio_element_info::origin_trans_l_arr (Translator* end) const
 {
-  return origin_trans_l_arr_;
+  Translator * t = origin_trans_l_;
+  Link_array<Translator> r;
+  do {
+    r.push (t);
+    t = t->daddy_trans_l_;
+  } while (t && t != end->daddy_trans_l_);
+  
+  return r;
 }
index 2c9de1f71799e36533c2f65a383b59309ab401bf..0ae3021d4670172be651ba9e1abd56df4b90f4ed 100644 (file)
@@ -49,7 +49,7 @@ Auto_change_iterator::change_to (Music_iterator *it, String to_type,
        Translator_group * dest = 
          it->report_to_l ()->find_create_translator_l (to_type, to_id);
        current->remove_translator_p (last);
-       dest->add_translator (last);
+       dest->add_group_translator (last);
       }
     else
       {
index a156379adbdcddf7477d79072af93dbbc4f3d392..4d7db9b45210cb619abc8d113a6f95000eaf7014 100644 (file)
@@ -77,11 +77,11 @@ Axis_group_interface::set_axes (Score_element*me,Axis a1, Axis a2)
   SCM sa1= gh_int2scm (a1);
   SCM sa2 = gh_int2scm (a2);
 
-  SCM prop = me->get_elt_property ("axes");
+  SCM axes = me->get_elt_property ("axes");
   
-  if (!gh_pair_p (prop)
-      || scm_memq (sa1, prop) == SCM_BOOL_F
-      || scm_memq (sa2, prop) == SCM_BOOL_F)
+  if (!gh_pair_p (axes)
+      || scm_memq (sa1, axes) == SCM_BOOL_F
+      || scm_memq (sa2, axes) == SCM_BOOL_F)
     {
       SCM ax = gh_cons (sa1, SCM_EOL);
       if (a1 != a2)
index dfa4d906fa9dfc66cd546c9ef023315ccd44a930..bbb1af823809e0aef7203143358f96d9879621d2 100644 (file)
@@ -90,7 +90,7 @@ Bar_engraver::do_removal_processing ()
 void
 Bar_engraver::do_process_music()
 {  
-  Translator * t = daddy_grav_l  ()->get_simple_translator ("Timing_engraver");
+  Translator * t = daddy_grav_l  ()->get_simple_translator ("Timing_engraver");        // UGH.!
 
   Timing_engraver * te = dynamic_cast<Timing_engraver*>(t);
   String which = (te) ? te->which_bar () : "";
index 34a0cb2eae3228113aa22b72c3212cd03c693f43..4fe7d7172f13a6684cf52acfc673978cd75b733c 100644 (file)
 #include "item.hh"
 #include "moment.hh"
 #include "engraver.hh"
-#include "protected-scm.hh"
+#include "translator-group.hh"
+
 
 class Bar_number_engraver : public Engraver
 {
 protected:
   Item* text_p_;
 
-  Protected_scm staffs_;
-
 protected:
   virtual void do_pre_move_processing ();
   virtual void acknowledge_element (Score_element_info);
+  virtual void do_creation_processing ();
   void create_items();
   void do_process_music ();
 public:
@@ -58,9 +58,16 @@ ADD_THIS_TRANSLATOR(Bar_number_engraver);
 Bar_number_engraver::Bar_number_engraver ()
 {
   text_p_ =0;
-  staffs_ = SCM_EOL;
 }
 
+void
+Bar_number_engraver::do_creation_processing ()
+{
+  /*
+    ugh: need to share code with mark_engraver
+   */
+  daddy_trans_l_->set_property ("staffsFound", SCM_EOL); 
+}
 
 
                                               
@@ -70,7 +77,10 @@ Bar_number_engraver::acknowledge_element (Score_element_info inf)
   Score_element * s = inf.elem_l_;
   if (Staff_symbol::has_interface (s))
     {
-      staffs_ = gh_cons (inf.elem_l_->self_scm (), staffs_);
+      SCM sts = get_property ("staffsFound");
+      SCM thisstaff = inf.elem_l_->self_scm ();
+      if (scm_memq (thisstaff, sts) == SCM_BOOL_F)
+       daddy_trans_l_->set_property ("staffsFound", gh_cons (thisstaff, sts));
     }
   else if (text_p_
           && dynamic_cast<Item*> (s)
@@ -88,7 +98,7 @@ Bar_number_engraver::do_pre_move_processing ()
 {
   if (text_p_)
     {
-      text_p_->set_elt_property ("side-support-elements", staffs_);
+      text_p_->set_elt_property ("side-support-elements", get_property ("staffsFound"));
       typeset_element (text_p_);
       text_p_ =0;
     }
index b48f31b25ac870527f12041d59b552e6dda41f86..aa3bc9760cfb4cbcb10de497d3692e678efa7f2c 100644 (file)
@@ -19,6 +19,7 @@ class Break_align_engraver : public Engraver
   Item *align_l_;
   Protected_scm column_alist_;
 protected:
+  virtual void do_removal_processing ();
   virtual void acknowledge_element(Score_element_info i);
   virtual void do_pre_move_processing ();
   void add_column (SCM);
@@ -40,6 +41,12 @@ Break_align_engraver::add_column (SCM smob)
   typeset_element (e);
 }
 
+void
+Break_align_engraver::do_removal_processing ()
+{
+  column_alist_ = SCM_EOL;
+}
+
 void
 Break_align_engraver::do_pre_move_processing ()
 {
index 08fdc53271e210e0e76cd7445982bbbd397763ba..730e4adc8e3cb241ab121e0b302dabcdca7d7025 100644 (file)
@@ -66,7 +66,7 @@ Change_iterator::do_process_and_next (Moment m)
        Translator_group * dest = 
          report_to_l ()->find_create_translator_l (to_type, to_id);
        current->remove_translator_p (last);
-       dest->add_translator (last);
+       dest->add_group_translator (last);
       }
     else
       {
index df8b2eb23f843fb74452b05e021a869efad46510..d448e716483d2ad86b9846e0cc1a9296a85e5c5c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <ctype.h>
 
+#include "translator-group.hh"
 #include "key-item.hh"
 #include "local-key-item.hh"
 #include "bar.hh"
 #include "staff-symbol-referencer.hh"
 #include "debug.hh"
 #include "command-request.hh"
-#include "array.hh"
 #include "engraver.hh"
 #include "direction.hh"
 #include "side-position-interface.hh"
 #include "item.hh"
 
 /// where is c-0 in the staff?
-class Clef_engraver : public  Engraver {
+class Clef_engraver : public  Engraver
+{
   Item * clef_p_;
   Item * octavate_p_;
   Clef_change_req * clef_req_l_;
@@ -50,15 +51,11 @@ public:
   Clef_engraver();
 
   bool  first_b_;
-  
-  Protected_scm current_settings_;
 };
 
 
 Clef_engraver::Clef_engraver()
 {
-  current_settings_ = SCM_EOL;
-
   first_b_ = true;
   clef_glyph_ = SCM_EOL;
   clef_p_ = 0;
@@ -108,13 +105,14 @@ Clef_engraver::set_type (String s)
 
   c0_position_i_ -= (int) octave_dir_ * 7;
 
-  SCM basic = get_property ("basicClefItemProperties");
-  current_settings_ = gh_cons (gh_cons (ly_symbol2scm ("glyph"), clef_glyph_), basic);
-  current_settings_ =
-    gh_cons (gh_cons (ly_symbol2scm ("c0-position"),
-                     gh_int2scm (c0_position_i_)),
-            current_settings_);
-  
+  SCM basic = ly_symbol2scm ("basicClefItemProperties");
+  SCM c0 = ly_symbol2scm ("c0-position");
+  SCM gl = ly_symbol2scm ("glyph");
+  daddy_trans_l_->execute_single_pushpop_property (basic, gl, SCM_UNDEFINED);
+  daddy_trans_l_->execute_single_pushpop_property (basic, c0, SCM_UNDEFINED);  
+  daddy_trans_l_->execute_single_pushpop_property (basic, gl, clef_glyph_);
+  daddy_trans_l_->execute_single_pushpop_property (basic, c0, gh_int2scm (c0_position_i_));
+
   return true;
 }
 
@@ -178,7 +176,7 @@ Clef_engraver::create_clef()
 {
   if (!clef_p_)
     {
-      Item *c= new Item ( current_settings_);
+      Item *c= new Item (get_property ("basicClefItemProperties"));
       announce_element (c, clef_req_l_);
 
       Staff_symbol_referencer::set_interface (c);
index c12283e8e43166bd1770bc5d01c1a1efc0bc0c28..847bb5d13e36d16d6ccb16484cd612cb7c776582 100644 (file)
@@ -27,38 +27,33 @@ Engraver_group_engraver::announce_element (Score_element_info info)
 void
 Engraver_group_engraver::do_announces()
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+  for (SCM p = trans_group_list_; gh_pair_p (p); p =gh_cdr ( p))
     {
-      if (Engraver_group_engraver *trg =  dynamic_cast <Engraver_group_engraver *> (p->car_))
-       trg->do_announces ();
+      Translator * t = unsmob_translator (gh_car (p));
+      dynamic_cast<Engraver_group_engraver*> (t)->do_announces ();
     }
-
+  
   while (announce_info_arr_.size ())
     {
       for (int j =0; j < announce_info_arr_.size(); j++)
        {
          Score_element_info info = announce_info_arr_[j];
          
-         for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+         for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr (p))
            {
-             if (!dynamic_cast <Engraver_group_engraver *> (p->car_))
-               {
-                 Engraver * eng = dynamic_cast<Engraver*> (p->car_);
-                 if (eng && eng!= info.origin_trans_l_arr (this)[0])
-                   eng->acknowledge_element (info);
-               }                 
+             Translator * t = unsmob_translator (gh_car (p));
+             Engraver * eng = dynamic_cast<Engraver*> (t);
+             if (eng && eng!= info.origin_trans_l_)
+               eng->acknowledge_element (info);
            }
        }
-      
       announce_info_arr_.clear ();
-      for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+      for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr ( p))
        {
-         if (!dynamic_cast <Engraver_group_engraver *> (p->car_))
-           {
-             Engraver * eng = dynamic_cast<Engraver*> (p->car_);
-             if (eng)
-               eng->process_acknowledged ();
-           }
+         Translator * t = unsmob_translator (gh_car (p));
+         Engraver * eng = dynamic_cast<Engraver*> (t);
+         if (eng)
+           eng->process_acknowledged ();
        }
     }
 }
index f7b66a62c3f6bf30ae9f9ec5d0e77b83d0b774f3..ae3a2f5a3e1b1992a96f69d27166cd25853ec4b8 100644 (file)
@@ -85,12 +85,6 @@ Grace_engraver_group::each (Method_pointer method)
 }
 
 
-void
-Grace_engraver_group::each (Const_method_pointer method) const
-{
- if (calling_self_b_)
-    Engraver_group_engraver::each (method);
-}
 ADD_THIS_TRANSLATOR(Grace_engraver_group);
 
 
index fcfad2a3391a34021f08b0476d535fb173f33b98..4bf89fe1da896647487f99e6b7283ce1e0c120a5 100644 (file)
@@ -87,12 +87,7 @@ Grace_performer_group::each (Method_pointer method)
 }
 
 
-void
-Grace_performer_group::each (Const_method_pointer method) const
-{
- if (calling_self_b_)
-    Performer_group_performer::each (method);
-}
+
 
 /*
   don't let the commands trickle up.
index d3d0e7221b7024d83614dc6b29aaab9c783070f7..bedc2f9dfd9bfa7bea3ce2e3adf85e58da856df3 100644 (file)
   JUNKTHIS!
  */
 #include <assert.h>
+
 #include "music-output-def.hh"
 #include "score.hh"
 #include "identifier.hh"
 #include "my-lily-lexer.hh"
 #include "debug.hh"
-#include "translator-group.hh"
 #include "ly-smobs.icc"
 
 
@@ -81,8 +81,6 @@ Class ## _identifier::do_print () const { \
 }
 
 
-
-DEFAULT_PRINT(Translator_group);
 DEFAULT_PRINT(Score);
 DEFAULT_PRINT(Music_output_def);
 
@@ -93,8 +91,6 @@ Class ## _identifier::do_str () const { \
   return String (#Class); \
 }
 
-
-DUMMY_STR(Translator_group);
 DUMMY_STR(Score);
 DUMMY_STR(Music_output_def);
 DUMMY_STR(Duration);
@@ -151,10 +147,8 @@ Class ## _identifier::Class ## _identifier (Class ## _identifier const &s) \
 
 
 IMPLEMENT_ID_CLASS(Duration);
-IMPLEMENT_ID_CLASS(Translator_group);
 IMPLEMENT_ID_CLASS(Score);
 IMPLEMENT_ID_CLASS(Music_output_def);
-VIRTUAL_ACCESSOR(Translator_group);
 VIRTUAL_ACCESSOR(Music_output_def);
 DEFAULT_ACCESSOR(Duration);
 DEFAULT_ACCESSOR(Score);
index 2d09970ab4bc268546fd77d435a8d24104c13fe6..b3b805ca0763218185a737c1b0b736c216a20bf5 100644 (file)
@@ -19,7 +19,7 @@
 struct Audio_element_info {
   Audio_element * elem_l_;
   Music *req_l_;
-  Link_array<Translator> origin_trans_l_arr_;
+  Translator *  origin_trans_l_;
   Link_array<Translator> origin_trans_l_arr (Translator*) const;  
 
   Audio_element_info (Audio_element*, Music*);
index 5c63b4fd2ad371313ccfd410d8d78d68af3c64a2..2ba5768a67f5ceab74cf2addb92d3b1653d72628 100644 (file)
@@ -28,7 +28,6 @@ protected:
   virtual void finish ();
   virtual void process ();
   virtual void each (Method_pointer);
-  virtual void each (Const_method_pointer) const;
   virtual void do_removal_processing () ;
   virtual void typeset_element (Score_element*);
   virtual bool do_try_music (Music *m);
index cfeb9884a00e2fe3d1491f02770a91a5560b28cd..5b05625b09e9ebe0d47fcccadbac2226fcb7722c 100644 (file)
@@ -27,7 +27,6 @@ protected:
   virtual void finish ();
   virtual void process ();
   virtual void each (Method_pointer);
-  virtual void each (Const_method_pointer) const;
   virtual void do_removal_processing () ;
   virtual void play_element (Audio_element*);
   virtual bool do_try_music (Music *m);
index 02587ce9788138e74c767052f1a8f2c22cf8cec4..2e39b1ff47479651488f7a16cd9bdaad503b6ed2 100644 (file)
@@ -15,7 +15,6 @@
 #include "smobs.hh"
 
 
-class Translator_group_identifier;
 class Output_def_identifier;
 class Score_identifier;
 class Duration_identifier;
@@ -43,7 +42,6 @@ struct Identifier : public Input {
   
   void error (String) const;
   String str () const;
-  IDACCESSOR(Translator_group)
   IDACCESSOR(Music_output_def)
   IDACCESSOR(Score)
   IDACCESSOR(Duration)
@@ -69,7 +67,6 @@ struct Class ## _identifier : Identifier {\
 }\
 
 
-DECLARE_ID_CLASS(Translator_group);
 DECLARE_ID_CLASS(Duration);
 DECLARE_ID_CLASS(Score);
 DECLARE_ID_CLASS(Music_output_def);
index e00a1c159cb622db9121a68407b7aaac0b6e329a..cda6f6584a6e1a7408a4ef9b3f00f91efe663582 100644 (file)
@@ -66,7 +66,7 @@ protected:
   virtual void acknowledge_element(Score_element_info);
   virtual void process_acknowledged ();
   virtual void do_pre_move_processing();
-  
+  virtual void do_removal_processing ();  
 private:
   void record_notehead(const String &context_id, Score_element * notehead);
   void record_lyric(const String &context_id, Score_element * lyric);
index 0b887470fc4d418729cf4bec0a70fc4073f44f5a..c8a49507839f0b59a868f9582ba1e8720c46225d 100644 (file)
@@ -39,6 +39,7 @@ public:
 class Push_translation_property : public Music
 {
 public:
+  VIRTUAL_COPY_CONS(Music);
 };
 
 /**
@@ -51,7 +52,12 @@ public:
 class Pop_translation_property : public Music
 {
 public:
+  VIRTUAL_COPY_CONS(Music);
 };
 
 
+void apply_push_property (Translator_group*trans, SCM syms, SCM eprop, SCM val);
+void apply_pop_property (Translator_group*trans, SCM syms, SCM eprop);
+
+
 #endif // PROPERTY_HH
index 5bb0d08e28d5ec260f9370ec5f1efd13580df7aa..126c232c8d6ed9991f59fb386046d7b37dd395e7 100644 (file)
 #include "lily-proto.hh"
 #include "virtual-methods.hh"
 #include "translator.hh"
-#include "cons.hh"
 #include "parray.hh"
-
+#include "smobs.hh"
 
 // egcs
 typedef void (Translator::*Method_pointer)(void);
-typedef void (Translator::*Const_method_pointer)(void) const; 
+
 class Scheme_hash_table;
+
+/*
+  should make a struct out of this, and move SCM list stuff in here.
+ */
+struct Translator_group_initializer {
+  static SCM modify_definition (SCM, SCM, bool);
+
+  static void set_acceptor (Translator*,SCM accepts, bool add);
+  static void add_element (Translator*,SCM name);
+  static void remove_element (Translator*,SCM name);
+  static void add_last_element (Translator*,SCM name);
+  static void apply_pushpop_property (Translator*trans, SCM syms, SCM eprop, SCM val);
+  static void add_push_property (Translator*, SCM,SCM,SCM);
+  static void add_pop_property (Translator*, SCM,SCM);  
+  
+};
+
 /** Make some kind of Elements from Requests. Elements are made by
   hierarchically grouped Translators
   */
 class Translator_group : public virtual Translator {
-  Array<String> consists_str_arr_;
-  Array<String> accepts_str_arr_;
-  Array<String> consists_end_str_arr_;
-  Scheme_hash_table *properties_dict_;
 
+  Scheme_hash_table *properties_dict () const;
   int iterator_count_;
-  friend class Interpretation_context_handle;
 
-protected:
-  Cons_list<Translator> trans_p_list_;
 
+  friend class Interpretation_context_handle;
+protected:
+  ~Translator_group ();
 public:
+  SCM add_translator (SCM, Translator*);
+  void execute_single_pushpop_property (SCM prop, SCM sym, SCM val);
   SCM get_property (SCM name_sym) const;
   void set_property (String var_name, SCM value);
   void set_property (SCM var_sym, SCM value);  
   Translator_group *where_defined (SCM name_sym) const;
 
   String id_str_;
-  void add_last_element (String s);
 
   VIRTUAL_COPY_CONS(Translator);
-  
-  void set_acceptor (String accepts, bool add);
-  void set_element (String elt, bool add);  
-  
   Translator_group(Translator_group const &);
   Translator_group();
-  void add_translator (Translator *trans_p);
+  void add_simple_translator (Translator *trans_p);
+  void add_group_translator (Translator *trans_p);
+
   
   /// Score_register = 0, Staff_registers = 1, etc)
   Translator_group* ancestor_l (int l=1);
@@ -63,14 +75,12 @@ public:
   void terminate_translator (Translator*r_l);
   Translator *remove_translator_p (Translator*trans_l);
   void check_removal ();
-
   Translator *get_simple_translator (String) const;
   Translator_group *find_existing_translator_l (String n, String id);
   Translator_group *find_create_translator_l (String n, String id);
   Link_array<Translator_group> path_to_acceptable_translator (String alias, Music_output_def*) const;
 
   Translator_group*get_default_interpreter();
-  virtual ~Translator_group ();
   
 protected:
   bool try_music_on_nongroup_children (Music *m);
@@ -84,7 +94,7 @@ protected:
   virtual void do_creation_processing();
   virtual void do_removal_processing();
   virtual void each (Method_pointer);
-  virtual void each (Const_method_pointer) const;
+
 };
 
 #endif // TRANSLATOR_GROUP_HH
index a40fd07275e2ea4534e57c4fa9c313a157fb4a32..2cca991105ce897032fe5c027d578a31768719eb 100644 (file)
 #include "lily-guile.hh"
 #include "parray.hh"
 #include "input.hh"
-
+#include "smobs.hh"
 
 /** Make some kind of #Element#s from Requests. Elements are made by
   hierarchically grouped #Translator#s
   */
 class Translator : public Input {
+  void init ();
 public:
   Music_output_def * output_def_l_;
   String type_str_;
@@ -33,7 +34,6 @@ public:
   VIRTUAL_COPY_CONS(Translator);
   Translator (Translator const &);
   Translator ();
-  virtual ~Translator ();
   
   Translator_group * daddy_trans_l_ ;
  
@@ -65,7 +65,19 @@ public:
   
   virtual Moment now_mom () const;  
 
-protected:
+  /*
+    ugh: bubbled up from Translator_group. 
+   */
+  SCM consists_name_list_;
+  SCM end_consists_name_list_;
+  SCM accepts_name_list_;
+  SCM simple_trans_list_;
+  SCM trans_group_list_;
+  SCM properties_scm_;
+  SCM property_pushes_;
+  DECLARE_SMOBS(Translator, dummy);
+
+public:
   /*
     UGH. Clean this up.
    */
@@ -78,7 +90,8 @@ protected:
     PROCESSED_REQS,
     ACKED_REQS,
     MOVE_DONE
-  } status;
+  } status_;                   // junkme
+protected:
 
   /*    
        @see{try_request}
@@ -112,5 +125,5 @@ extern Dictionary<Translator*> *global_translator_dict_p;
 void add_translator (Translator*trans_p);
 
 Translator*get_translator_l (String s);
-
+Translator *unsmob_translator (SCM);
 #endif // TRANSLATOR_HH
index f19ddf1c1f78f34cb8d371c1c87a72ddc171008a..8fcae86fd28e78dbe8a839a5f97de08c09aaaa81 100644 (file)
@@ -22,7 +22,8 @@
 /**
   Make the key signature.
  */
-class Key_engraver : public Engraver {
+class Key_engraver : public Engraver
+{
   void create_key(bool);
   void read_req (Key_change_req const * r);
 
@@ -37,6 +38,7 @@ public:
     
 protected:
   virtual void do_creation_processing();
+  virtual void do_removal_processing ();
   virtual bool do_try_music (Music *req_l);
   virtual void do_process_music();
   virtual void do_pre_move_processing();
@@ -45,6 +47,12 @@ protected:
 };
 
 
+void
+Key_engraver::do_removal_processing ()
+{
+  old_accs_ = SCM_EOL;         // unprotect can be called from dtor.
+}
+
 Key_engraver::Key_engraver ()
 {
   keyreq_l_ = 0;
index 90f4ba43f4091e1a2a77187a8a268b5502969709..09378ba9617a98e79aa7d6eb18abb4e6700821c7 100644 (file)
@@ -39,7 +39,7 @@
 #include "identifier.hh"
 #include "version.hh"
 #include "mudela-version.hh"
-
+#include "translator-group.hh"
 void strip_trailing_white (String&);
 void strip_leading_white (String&);
 
@@ -477,6 +477,9 @@ My_lily_lexer::scan_escaped_word (String str)
        } else if (gh_number_p (sid)) {
                yylval.scm = sid;
                return NUMBER_IDENTIFIER;
+       } else if (Translator* tr = unsmob_translator (sid)) {
+               yylval.scm = sid;
+               return TRANSLATOR_IDENTIFIER;
        } else if (Music * mus =unsmob_music (sid)) {
                yylval.scm = sid;
                
index c17f9ce5154aae60111f44c158e83e4a6b0b411d..5cc40bc936503dfbb5de4efe9ae4743bc8afa697 100644 (file)
 #include "lyric-phrasing-engraver.hh"
 #include "note-head.hh"
 #include "translator-group.hh"
-#include "side-position-interface.hh"
-#include "ly-smobs.icc"
 #include "spanner.hh"
-#include "paper-def.hh"
 
 
 String get_context_id(Translator_group * ancestor, const char * type);
@@ -56,6 +53,17 @@ Lyric_phrasing_engraver::~Lyric_phrasing_engraver()
    */
 }
 
+void
+Lyric_phrasing_engraver::do_removal_processing ()
+{
+  /*
+    but do need to unprotect alist_, since Engravers are gc'd now.
+   */
+
+  voice_alist_ = SCM_EOL;
+}
+
+
 Syllable_group * 
 Lyric_phrasing_engraver::lookup_context_id(const String &context_id)
 {
@@ -275,263 +283,3 @@ Lyric_phrasing_engraver::do_pre_move_processing ()
 
 
 
-/*=========================================================================================*/
-
-/** Syllable_group is a class to be smobbed and entered as data in the association list
-    member of the Lyric_phrasing_engraver class.
-*/
-
-Syllable_group::Syllable_group()
-{
-  first_in_phrase_b_=true;
-  melisma_b_ = false;
-  clear();
-}
-
-void 
-Syllable_group::clear()
-{
-  notehead_l_=0;
-  lyric_list_.clear();
-  longest_lyric_l_=0;
-  shortest_lyric_l_=0;
-  melisma_b_ = false;
-  group_translation_f_ = 0.0;
-}
-  
-void
-Syllable_group::copy( Syllable_group *from)
-{
-  notehead_l_ = from->notehead_l_;
-  lyric_list_ = from->lyric_list_;
-  longest_lyric_l_ = from->longest_lyric_l_;
-  shortest_lyric_l_ = from->shortest_lyric_l_;
-  melisma_b_ = from->melisma_b_;
-  alignment_i_ = from->alignment_i_;
-  first_in_phrase_b_ = from->first_in_phrase_b_;
-  group_translation_f_ = from->group_translation_f_;
-}
-
-void 
-Syllable_group::set_first_in_phrase(bool f) 
-{ 
-  first_in_phrase_b_ = f; 
-}
-
-void 
-Syllable_group::set_notehead(Score_element * notehead)
-{
-  if(!notehead_l_) {
-    /* there should only be a single notehead, so silently ignore any extras */
-    notehead_l_=notehead;
-  }
-}
-
-void 
-Syllable_group::add_lyric(Score_element * lyric)
-{
-  lyric_list_.push(lyric);
-  /* record longest and shortest lyrics */
-  if( longest_lyric_l_ ) {
-    if(lyric->extent(X_AXIS).length() > (longest_lyric_l_->extent(X_AXIS)).length())
-      longest_lyric_l_ = lyric;
-    if(lyric->extent(X_AXIS).length() < (shortest_lyric_l_->extent(X_AXIS)).length())
-      shortest_lyric_l_ = lyric;
-  }
-  else
-    longest_lyric_l_ = shortest_lyric_l_ = lyric;
-}
-
-void 
-Syllable_group::add_extender(Score_element * extender)
-{
-  if(notehead_l_ && melisma_b_) {
-    dynamic_cast<Spanner*>(extender)->set_bound (RIGHT, notehead_l_);
-    // should the extender finish at the right of the last note of the melisma, or the left?
-    // Comments in lyric-extender.hh say left, but right looks better to me. GP.
-
-    // Left:
-//     extender->set_elt_property("right-trim-amount", gh_double2scm(0.0));
-
-    // Right:
-    Real ss = extender->paper_l ()->get_var ("staffspace");
-    extender->set_elt_property("right-trim-amount", 
-                              gh_double2scm(-notehead_l_->extent(X_AXIS).length()/ss));
-  }
-}
-
-bool 
-Syllable_group::set_lyric_align(const char *punc, Score_element *default_notehead_l)
-{
-  if(lyric_list_.size()==0) {
-    // No lyrics: nothing to do.
-    return true;
-  }
-
-  Score_element * lyric;
-  alignment_i_ = appropriate_alignment(punc);
-
-  // If there was no notehead in the matching voice context, use the first 
-  // notehead caught from any voice context (any port in a storm).
-  if(!notehead_l_) {
-    notehead_l_ = default_notehead_l;
-  }
-
-  group_translation_f_ = amount_to_translate();
-
-  // set the x alignment of each lyric
-  for(int l = 0; l < lyric_list_.size(); l++) {
-    lyric = lyric_list_[l];
-    lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_));
-    // centre on notehead ... if we have one. 
-    if(notehead_l_) {
-      lyric->set_parent(notehead_l_, X_AXIS);
-      lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS);
-      // reference is on the right of the notehead; move it left half way, and add translation
-      lyric->translate_axis (group_translation_f_-(notehead_l_->extent(X_AXIS)).center(), X_AXIS);
-    }
-  }
-  return (notehead_l_);
-}
-
-/** determine the distance to translate lyrics to get correct alignment
-    Rules: If alignment is centre, translate = 0
-           Otherwise,
-             If (length of longest lyric) < 2 * (length of shortest lyric),
-                - centre longest lyric on notehead
-             Otherwise
-                - move so shortest lyric just reaches notehead centre
-*/
-Real 
-Syllable_group::amount_to_translate()
-{
-  Real translate = 0.0;
-  if(alignment_i_ != CENTER) {
-    // FIXME: do we really know the lyric extent here? Some font sizing comes later?
-    if((longest_lyric_l_->extent(X_AXIS)).length() <
-       (shortest_lyric_l_->extent(X_AXIS)).length() * 2 )
-      translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2;
-    else
-      translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length();
-  }
-  return translate;
-}
-
-
-/** determine what alignment we want.
-    Rules: if first_in_phrase_b_ is set, then alignment is LEFT.
-           otherwise if each syllable ends in punctuation, then alignment is RIGHT
-          otherwise alignment is centre.
-*/
-int 
-Syllable_group::appropriate_alignment(const char *punc)
-{
-  if(first_in_phrase_b_)
-    return LEFT;
-
-  Score_element * lyric;
-  bool end_phrase = true;
-
-  for(int l = 0; l < lyric_list_.size() && end_phrase; l++) {
-    lyric = lyric_list_[l];
-    SCM lyric_scm = lyric->get_elt_property("text");
-    String lyric_str = gh_string_p(lyric_scm)?ly_scm2string(lyric_scm):"";
-    char lastchar;
-    if(lyric_str.length_i()>0) {
-      lastchar = lyric_str[lyric_str.length_i()-1];
-      /* If it doesn't end in punctuation then it ain't an end of phrase */
-      if(! strchr(punc, lastchar)) {
-       /* Special case: trailing space. Here examine the previous character and reverse the
-          sense of the test (i.e. trailing space makes a break without punctuation, or 
-          suppresses a break with punctuation).
-          This behaviour can be suppressed by including a space in the 
-          phrasingPunctuation property, in which case trailing space always means 
-          the same as punctuation.
-
-          FIXME: The extra space throws alignment out a bit.
-       */
-       if(lastchar == ' ') {
-         if(lyric_str.length_i()>1) {
-           lastchar = lyric_str[lyric_str.length_i()-2];
-           if(strchr(punc, lastchar))
-             end_phrase=false;
-         }
-       }
-       else
-         end_phrase=false;
-      }
-    }
-  }
-  if(end_phrase)
-    return RIGHT;
-
-  return CENTER;
-}
-
-/** We don't know about the melisma until after the initial alignment work is done, so go
-    back and fix the alignment when we DO know.
-*/
-void
-Syllable_group::adjust_melisma_align()
-{
-  if(notehead_l_ && lyric_list_.size()) {
-    // override any previous offset adjustments
-    Real translation = -group_translation_f_;
-    // melisma aligning:
-    switch (alignment_i_) {
-      //  case LEFT: // that's all
-    case CENTER: // move right so smallest lyric is left-aligned on notehead
-      translation += (shortest_lyric_l_->extent(X_AXIS)).length()/2;
-      break;
-    case RIGHT: // move right so smallest lyric is left-aligned on notehead
-      translation += (shortest_lyric_l_->extent(X_AXIS)).length();
-      break;
-    }
-    group_translation_f_ += translation;
-    for(int l = 0; l < lyric_list_.size(); l++) {
-      lyric_list_[l]->translate_axis (translation, X_AXIS);
-    }
-  }
-}
-
-
-bool
-Syllable_group::is_empty()
-{
-  return lyric_list_.size()==0;
-}
-
-void
-Syllable_group::next_lyric()
-{
-  first_in_phrase_b_ = (alignment_i_ == RIGHT);
-  clear();
-}
-
-/* SMOB */
-
-
-
-SCM
-Syllable_group::mark_smob (SCM)
-{
-  return SCM_EOL;
-}
-
-int
-Syllable_group::print_smob (SCM, SCM port, scm_print_state * )
-{
-  scm_puts ("#<Syllable_group>", port);
-  return 1;
-}
-
-IMPLEMENT_UNSMOB(Syllable_group, voice_entry);
-IMPLEMENT_SIMPLE_SMOBS(Syllable_group);
-IMPLEMENT_DEFAULT_EQUAL_P(Syllable_group);
-
-SCM
-Syllable_group::make_entry ()
-{
-  Syllable_group *vi = new Syllable_group;
-  return vi->smobbed_self ();
-}
index b57bafa3e28b2c280535a81553f76d31d2bf506b..9ada64765fad07f3d154e6c986bc7e5f4e5d92bc 100644 (file)
@@ -15,7 +15,7 @@
 #include "lily-guile.hh"
 #include "paper-column.hh"
 #include "paper-def.hh"
-#include "protected-scm.hh"
+
 #include "side-position-interface.hh"
 #include "staff-symbol-referencer.hh"
 #include "item.hh"
@@ -32,7 +32,6 @@ public:
   Mark_engraver ();
 protected:
   Item* text_p_;
-  Protected_scm staffs_;
   
 protected:
   virtual void do_pre_move_processing ();
@@ -41,6 +40,8 @@ protected:
   virtual bool do_try_music (Music *req_l);
   virtual void do_process_music ();
   virtual void do_post_move_processing ();
+  virtual void do_creation_processing ();
+  
 private:
   Mark_req * mark_req_l_;
 };
@@ -53,9 +54,13 @@ Mark_engraver::Mark_engraver ()
 {
   text_p_ =0;
   mark_req_l_ = 0;
-  staffs_ = SCM_EOL;
 }
 
+void
+Mark_engraver::do_creation_processing ()
+{
+  daddy_trans_l_->set_property ("staffsFound", SCM_EOL); // ugh: sharing with barnumber grav.
+}
 
 
 void
@@ -64,7 +69,10 @@ Mark_engraver::acknowledge_element (Score_element_info inf)
   Score_element * s = inf.elem_l_;
   if (Staff_symbol::has_interface (s))
     {
-      staffs_ = gh_cons (inf.elem_l_->self_scm (), staffs_);
+      SCM sts = get_property ("staffsFound");
+      SCM thisstaff = inf.elem_l_->self_scm ();
+      if (scm_memq (thisstaff, sts) == SCM_BOOL_F)
+       daddy_trans_l_->set_property ("staffsFound", gh_cons (thisstaff, sts));
     }
   else if (text_p_ && Bar::has_interface (s))
     {
@@ -81,7 +89,7 @@ Mark_engraver::do_pre_move_processing ()
 {
   if (text_p_)
     {
-      text_p_->set_elt_property("side-support-elements" , staffs_);
+      text_p_->set_elt_property("side-support-elements" , get_property ("staffsFound"));
       typeset_element (text_p_);
       text_p_ =0;
     }
index 07895d86e2eec35dd5f6fd85c589c5581682d19d..a0107291a58a2ee7829c54407a9396e0c2c1b27c 100644 (file)
@@ -50,15 +50,17 @@ Music_output_def::assign_translator (Translator_group*tp)
     {
       tp->warning (_("Interpretation context with empty type"));
     }
-  translator_p_dict_p_->set (s, new Translator_group_identifier (tp, 0));
+
+  SCM tr = tp->self_scm ();
+  scm_unprotect_object (tr);
+  translator_p_dict_p_->set (s, tr);
 }
 
 Translator*
 Music_output_def::find_translator_l (String name) const
 {
   if (translator_p_dict_p_->elem_b (name))
-    return translator_p_dict_p_->elem (name)->access_content_Translator_group (false);
+    return unsmob_translator (translator_p_dict_p_->scm_elem (name));
 
   map<String, Translator*>::const_iterator ki
     =global_translator_dict_p->find (name);
@@ -77,6 +79,7 @@ Music_output_def::get_global_translator_p ()
   if (!t)
     error (_f ("can't find `%s' context", "Score"));
   t = t->clone ();
+
   t->output_def_l_ = this;
   Global_translator *g = dynamic_cast <Global_translator *> (t);
   t->add_processing ();
index bb7b882e36dc261637d8eb36c9ce13cde659a94a..84a0b042d82afc4df8aba23e0942d9cacfa40d6a 100644 (file)
@@ -198,14 +198,14 @@ yylex (YYSTYPE *s,  void * v_l)
 %token <pitch> CHORDMODIFIER_PITCH
 %token <id>    DURATION_IDENTIFIER
 %token <id>    IDENTIFIER
-%token <id>    TRANS_IDENTIFIER
+
 
 %token <id>    SCORE_IDENTIFIER
 %token <id>    MUSIC_OUTPUT_DEF_IDENTIFIER
 
 %token <scm>   NUMBER_IDENTIFIER
 %token <scm>   REQUEST_IDENTIFIER
-%token <scm>   MUSIC_IDENTIFIER
+%token <scm>   MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
 %token <scm>   STRING_IDENTIFIER SCM_IDENTIFIER 
 %token <scm>   DURATION RESTNAME
 %token <scm>   STRING 
@@ -388,7 +388,7 @@ identifier_init:
                $$ = (new Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER))->self_scm();
        }
        | translator_spec_block {
-               $$ = (new Translator_group_identifier ($1, TRANS_IDENTIFIER))->self_scm();
+               $$ = $1->self_scm ();
        }
        | Music  {
                $$ = $1->self_scm ();
@@ -418,8 +418,10 @@ translator_spec_block:
        ;
 
 translator_spec_body:
-       TRANS_IDENTIFIER        {
-               $$ = $1->access_content_Translator_group (true);
+       TRANSLATOR_IDENTIFIER   {
+               SCM trs = $1;
+               Translator*tr = unsmob_translator (trs);
+               $$ = dynamic_cast<Translator_group*> (tr->clone ());
                $$-> set_spot (THIS->here_input ());
        }
        | TYPE STRING semicolon {
@@ -449,23 +451,31 @@ translator_spec_body:
                
                tg->set_property (ly_scm2string ($2), v);
        }
+       | translator_spec_body PUSHPROPERTY
+                               embedded_scm embedded_scm embedded_scm {
+               Translator_group_initializer::add_push_property ($$, $3, $4, $5);
+       }
+       | translator_spec_body POPPROPERTY
+               embedded_scm embedded_scm  {
+               Translator_group_initializer::add_pop_property ($$, $3, $4);
+       }
        | translator_spec_body NAME STRING semicolon {
                $$->type_str_ = ly_scm2string ($3);
        }
        | translator_spec_body CONSISTS STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), true);
+               Translator_group_initializer::add_element ($$, $3);
        }
        | translator_spec_body CONSISTSEND STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), true);
+               Translator_group_initializer::add_last_element ($$, $3);
        }
        | translator_spec_body ACCEPTS STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_acceptor (ly_scm2string ($3), true);
+               Translator_group_initializer::set_acceptor ($$, $3,true);
        }
        | translator_spec_body DENIES STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_acceptor (ly_scm2string ($3), false);
+               Translator_group_initializer::set_acceptor ($$, $3,false);
        }
        | translator_spec_body REMOVE STRING semicolon {
-               dynamic_cast<Translator_group*> ($$)-> set_element (ly_scm2string ($3), false);
+               Translator_group_initializer::remove_element ($$, $3);
        }
        ;
 
index 1f57157c48f954039883ccfb16988e0f59f0ee8f..3a72a587a959865256883b60abb0acd86d56ad94 100644 (file)
@@ -101,7 +101,7 @@ Part_combine_music_iterator::change_to (Music_iterator *it, String to_type,
        Translator_group * dest = 
          it->report_to_l ()->find_create_translator_l (to_type, to_id);
        current->remove_translator_p (last);
-       dest->add_translator (last);
+       dest->add_group_translator (last);
       }
     else
       {
index 7a38830b530ebbe381491b634e1409f750f05510..0c07bf694f8af4b7f1ac7d43bab1076dc39ca5f7 100644 (file)
@@ -22,48 +22,44 @@ Performer_group_performer::announce_element (Audio_element_info info)
   Performer::announce_element (info);
 }
 
+
+
 void
 Performer_group_performer::do_announces()
 {
-   for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+  for (SCM p = trans_group_list_; gh_pair_p (p); p =gh_cdr ( p))
     {
-      if (Performer_group_performer *trg =  dynamic_cast <Performer_group_performer *> (p->car_))
-       trg->do_announces ();
+      Translator * t = unsmob_translator (gh_car (p));
+      dynamic_cast<Performer_group_performer*> (t)->do_announces ();
     }
-
   
-
-
   while (announce_info_arr_.size ())
     {
       for (int j =0; j < announce_info_arr_.size(); j++)
        {
          Audio_element_info info = announce_info_arr_[j];
-         for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-           {
-             if (!dynamic_cast <Performer_group_performer *> (p->car_))
-               {
-                 Performer * eng = dynamic_cast<Performer*> (p->car_);
-                 // urg, huh? core dump?
-                 //if (eng && eng!= info.origin_trans_l_arr ()[0])
-                 if (eng && info.origin_trans_l_arr (this).size ()
-                     && eng!= info.origin_trans_l_arr (this)[0])
-                   eng->acknowledge_element (info);
-               }
-           }
-         announce_info_arr_.clear ();
-      
-      
-         for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+         
+         for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr (p))
            {
-             if (!dynamic_cast <Performer_group_performer *> (p->car_))
-               {
-                 Performer * eng = dynamic_cast<Performer*> (p->car_);
-                 if (eng)
-                   eng->process_acknowledged ();
-               }
+             Translator * t = unsmob_translator (gh_car (p));
+             Performer * eng = dynamic_cast<Performer*> (t);
+             if (eng && eng!= info.origin_trans_l_)
+               eng->acknowledge_element (info);
            }
        }
+      announce_info_arr_.clear ();
+      for (SCM p = simple_trans_list_; gh_pair_p (p); p = gh_cdr ( p))
+       {
+         Translator * t = unsmob_translator (gh_car (p));
+         Performer * eng = dynamic_cast<Performer*> (t);
+         if (eng)
+           eng->process_acknowledged ();
+       }
     }
 }
 
+
+
+
+
+
index fe706b01f9528740a5a02b68085f3e3ad34590e8..8cf1c972f7118ae5b16d350cb4c5a26580688f9d 100644 (file)
@@ -45,6 +45,7 @@ Performer::process_acknowledged ()
 void
 Performer::announce_element (Audio_element_info i)
 {
-  i.origin_trans_l_arr_.push (this);
+  if (!i.origin_trans_l_)
+    i.origin_trans_l_= this;
   daddy_perf_l()->announce_element (i);
 }
index 6b1fd8f7c1d707de9aabd20c8ff4b16d034ad8ce..b9688e5de717c89b1c8581c2f6fc604d5328ba1c 100644 (file)
@@ -182,15 +182,8 @@ Piano_pedal_engraver::do_process_music ()
 
       if (gh_string_p (s))
        {
-         if (p->name_ == String ("Sustain"))
-           {
-             // fixme: Item should be sufficient.
-             p->item_p_ = new Item (get_property ("basicSustainPedalProperties"));
-           }
-         else
-           {
-             p->item_p_ = new Item (get_property ("basicPedalProperties"));
-           }
+         String propname = String ("basic")+  p->name_ + "PedalProperties";
+         p->item_p_ = new Item (get_property (propname.ch_C()));
          p->item_p_->set_elt_property ("text", s);
          // guh
 
index e7baf2ec253d21434c3669b373fc1c21c0d39fb4..1e5a16b931ae2e849ee3e21873a86ad3fb325130 100644 (file)
@@ -9,11 +9,14 @@
 
 #include "lily-guile.hh"
 #include "engraver.hh"
-#include "protected-scm.hh"
 #include "dictionary.hh"
 #include "score-element.hh"
 #include "scm-hash.hh"
 
+/*
+  JUNKME: should use pushproperty everywhere.
+  
+ */
 class Property_engraver : public Engraver
 {
   /*
@@ -99,12 +102,12 @@ Property_engraver::apply_properties (SCM p, Score_element *e)
       SCM type_p   = gh_cadr (entry);
       SCM elt_prop_sym = gh_caddr (entry);
 
-      SCM preset = e->get_elt_property (elt_prop_sym); // scm_assq(elt_prop_sym, e->property_alist_);
-      if (preset != SCM_EOL)
+      SCM preset = scm_assq(elt_prop_sym, e->mutable_property_alist_);
+      if (preset != SCM_BOOL_F)
        continue;
   
       SCM val = get_property (prop_sym);
-     
+
       if (val == SCM_UNDEFINED)
        ;                       // Not defined in context.
       else if (gh_apply (type_p, scm_listify (val, SCM_UNDEFINED))
index 0e50832e64a7d55013b491b3366e171c7cab123d..41b0ed5406edbebe6c74e440a5c98f587e59c754 100644 (file)
@@ -28,20 +28,11 @@ void
 Push_property_iterator::do_process_and_next (Moment m)
 {
   SCM syms = music_l_->get_mus_property ("symbols");
-  SCM  eprop = music_l_->get_mus_property ("element-property");
+  SCM eprop = music_l_->get_mus_property ("element-property");
   SCM val = music_l_->get_mus_property ("element-value");
 
-  for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
-    {
-      SCM sym = gh_car (s);
-      if (gh_symbol_p(sym))
-      {
-       SCM prev = report_to_l ()->get_property (sym);
-
-       prev = gh_cons (gh_cons (eprop, val), prev);
-       report_to_l ()->set_property (gh_car (s), prev);
-      }
-    }
+  Translator_group_initializer::apply_pushpop_property (report_to_l (), syms,eprop, val);
+  
   Music_iterator::do_process_and_next (m);
 }
 
@@ -50,23 +41,7 @@ Pop_property_iterator::do_process_and_next (Moment m)
 {
   SCM syms = music_l_->get_mus_property ("symbols");
   SCM eprop = music_l_->get_mus_property ("element-property");
-  for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s)) 
-    {
-    SCM sym = gh_car (s);
-    if (gh_symbol_p(sym))
-      {
-       SCM prev = report_to_l ()->get_property (sym);
-
-       SCM newprops= SCM_EOL ;
-       while (gh_pair_p (prev) && gh_caar (prev) != eprop)
-         {
-           newprops = gh_cons (gh_car (prev), newprops);
-           prev = gh_cdr (prev);
-         }
-
-       newprops = scm_reverse_x (newprops, gh_cdr (prev));
-       report_to_l ()->set_property (sym, newprops);
-      }
-    }
+  Translator_group_initializer::apply_pushpop_property (report_to_l (), syms, eprop, SCM_UNDEFINED);
+  
   Music_iterator::do_process_and_next (m);
 }
index 98747444146aadb78410bcc6f2bf974f46d1c5bf..2cae99cb0928efa7c90261d7decb198cc91bc921 100644 (file)
@@ -208,7 +208,7 @@ Repeat_engraver::do_process_music ()
     return;
 
   Bar_engraver* bar_engraver_l = dynamic_cast <Bar_engraver*>
-    (daddy_grav_l ()->get_simple_translator ("Bar_engraver"));
+    (daddy_grav_l ()->get_simple_translator ("Bar_engraver")); // UGH
 
   /*
     Do all the events that need to be done now.
index 49493167f39e3d8e7704bc06f9b3c583d53298f0..26a62293fcec8cf03c43014bc331b8a6876d3323 100644 (file)
@@ -189,10 +189,13 @@ Score_element::paper_l ()  const
 Lookup const *
 Score_element::lookup_l () const
 {
+  /*
+    URG junkthis, caching is clumsy.
+   */
   if (!lookup_l_)
     {
       Score_element * urg = (Score_element*)this;
-      SCM sz = urg->remove_elt_property ("fontsize");
+      SCM sz = urg->remove_elt_property ("font-size");
       int i = (gh_number_p (sz))
        ? gh_scm2int  (sz)
        : 0;
index ad868ae9e3af77df8cd93ac8e467c67f3fa30c9c..1908644904f4ba32ce95e0b1131f8eb54ac25a66 100644 (file)
@@ -47,7 +47,7 @@ void
 Score_performer::announce_element (Audio_element_info info)
 {
   announce_info_arr_.push (info);
-  info.origin_trans_l_arr_.push (this);
+
 
   /*
     huh?
index 75e397aab8a9686fdedfe48f88944e3b264a0a1a..4f33c853f1a37edded37c8a7bd8cc60374478e0f 100644 (file)
@@ -95,7 +95,8 @@ Score::run_translator (Music_output_def *odef_l)
     }
 
   Music_output * output = trans_p->get_output_p();
-  delete trans_p;
+  scm_unprotect_object (trans_p->self_scm ());
+  
   if(verbose_global_b)
     progress_indication (_f ("elapsed time: %.2f seconds",  timer.read ()));
 
diff --git a/lily/syllable-group.cc b/lily/syllable-group.cc
new file mode 100644 (file)
index 0000000..a0cf73d
--- /dev/null
@@ -0,0 +1,268 @@
+#include <string.h>
+
+#include "lyric-phrasing-engraver.hh"
+#include "note-head.hh"
+#include "translator-group.hh"
+#include "side-position-interface.hh"
+#include "ly-smobs.icc"
+#include "spanner.hh"
+#include "paper-def.hh"
+
+
+/*=========================================================================================*/
+
+/** Syllable_group is a class to be smobbed and entered as data in the association list
+    member of the Lyric_phrasing_engraver class.
+*/
+
+Syllable_group::Syllable_group()
+{
+  first_in_phrase_b_=true;
+  melisma_b_ = false;
+  clear();
+}
+
+void 
+Syllable_group::clear()
+{
+  notehead_l_=0;
+  lyric_list_.clear();
+  longest_lyric_l_=0;
+  shortest_lyric_l_=0;
+  melisma_b_ = false;
+  group_translation_f_ = 0.0;
+}
+  
+void
+Syllable_group::copy( Syllable_group *from)
+{
+  notehead_l_ = from->notehead_l_;
+  lyric_list_ = from->lyric_list_;
+  longest_lyric_l_ = from->longest_lyric_l_;
+  shortest_lyric_l_ = from->shortest_lyric_l_;
+  melisma_b_ = from->melisma_b_;
+  alignment_i_ = from->alignment_i_;
+  first_in_phrase_b_ = from->first_in_phrase_b_;
+  group_translation_f_ = from->group_translation_f_;
+}
+
+void 
+Syllable_group::set_first_in_phrase(bool f) 
+{ 
+  first_in_phrase_b_ = f; 
+}
+
+void 
+Syllable_group::set_notehead(Score_element * notehead)
+{
+  if(!notehead_l_) {
+    /* there should only be a single notehead, so silently ignore any extras */
+    notehead_l_=notehead;
+  }
+}
+
+void 
+Syllable_group::add_lyric(Score_element * lyric)
+{
+  lyric_list_.push(lyric);
+  /* record longest and shortest lyrics */
+  if( longest_lyric_l_ ) {
+    if(lyric->extent(X_AXIS).length() > (longest_lyric_l_->extent(X_AXIS)).length())
+      longest_lyric_l_ = lyric;
+    if(lyric->extent(X_AXIS).length() < (shortest_lyric_l_->extent(X_AXIS)).length())
+      shortest_lyric_l_ = lyric;
+  }
+  else
+    longest_lyric_l_ = shortest_lyric_l_ = lyric;
+}
+
+void 
+Syllable_group::add_extender(Score_element * extender)
+{
+  if(notehead_l_ && melisma_b_) {
+    dynamic_cast<Spanner*>(extender)->set_bound (RIGHT, notehead_l_);
+    // should the extender finish at the right of the last note of the melisma, or the left?
+    // Comments in lyric-extender.hh say left, but right looks better to me. GP.
+
+    // Left:
+//     extender->set_elt_property("right-trim-amount", gh_double2scm(0.0));
+
+    // Right:
+    Real ss = extender->paper_l ()->get_var ("staffspace");
+    extender->set_elt_property("right-trim-amount", 
+                              gh_double2scm(-notehead_l_->extent(X_AXIS).length()/ss));
+  }
+}
+
+bool 
+Syllable_group::set_lyric_align(const char *punc, Score_element *default_notehead_l)
+{
+  if(lyric_list_.size()==0) {
+    // No lyrics: nothing to do.
+    return true;
+  }
+
+  Score_element * lyric;
+  alignment_i_ = appropriate_alignment(punc);
+
+  // If there was no notehead in the matching voice context, use the first 
+  // notehead caught from any voice context (any port in a storm).
+  if(!notehead_l_) {
+    notehead_l_ = default_notehead_l;
+  }
+
+  group_translation_f_ = amount_to_translate();
+
+  // set the x alignment of each lyric
+  for(int l = 0; l < lyric_list_.size(); l++) {
+    lyric = lyric_list_[l];
+    lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_));
+    // centre on notehead ... if we have one. 
+    if(notehead_l_) {
+      lyric->set_parent(notehead_l_, X_AXIS);
+      lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS);
+      // reference is on the right of the notehead; move it left half way, and add translation
+      lyric->translate_axis (group_translation_f_-(notehead_l_->extent(X_AXIS)).center(), X_AXIS);
+    }
+  }
+  return (notehead_l_);
+}
+
+/** determine the distance to translate lyrics to get correct alignment
+    Rules: If alignment is centre, translate = 0
+           Otherwise,
+             If (length of longest lyric) < 2 * (length of shortest lyric),
+                - centre longest lyric on notehead
+             Otherwise
+                - move so shortest lyric just reaches notehead centre
+*/
+Real 
+Syllable_group::amount_to_translate()
+{
+  Real translate = 0.0;
+  if(alignment_i_ != CENTER) {
+    // FIXME: do we really know the lyric extent here? Some font sizing comes later?
+    if((longest_lyric_l_->extent(X_AXIS)).length() <
+       (shortest_lyric_l_->extent(X_AXIS)).length() * 2 )
+      translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2;
+    else
+      translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length();
+  }
+  return translate;
+}
+
+
+/** determine what alignment we want.
+    Rules: if first_in_phrase_b_ is set, then alignment is LEFT.
+           otherwise if each syllable ends in punctuation, then alignment is RIGHT
+          otherwise alignment is centre.
+*/
+int 
+Syllable_group::appropriate_alignment(const char *punc)
+{
+  if(first_in_phrase_b_)
+    return LEFT;
+
+  Score_element * lyric;
+  bool end_phrase = true;
+
+  for(int l = 0; l < lyric_list_.size() && end_phrase; l++) {
+    lyric = lyric_list_[l];
+    SCM lyric_scm = lyric->get_elt_property("text");
+    String lyric_str = gh_string_p(lyric_scm)?ly_scm2string(lyric_scm):"";
+    char lastchar;
+    if(lyric_str.length_i()>0) {
+      lastchar = lyric_str[lyric_str.length_i()-1];
+      /* If it doesn't end in punctuation then it ain't an end of phrase */
+      if(! strchr(punc, lastchar)) {
+       /* Special case: trailing space. Here examine the previous character and reverse the
+          sense of the test (i.e. trailing space makes a break without punctuation, or 
+          suppresses a break with punctuation).
+          This behaviour can be suppressed by including a space in the 
+          phrasingPunctuation property, in which case trailing space always means 
+          the same as punctuation.
+
+          FIXME: The extra space throws alignment out a bit.
+       */
+       if(lastchar == ' ') {
+         if(lyric_str.length_i()>1) {
+           lastchar = lyric_str[lyric_str.length_i()-2];
+           if(strchr(punc, lastchar))
+             end_phrase=false;
+         }
+       }
+       else
+         end_phrase=false;
+      }
+    }
+  }
+  if(end_phrase)
+    return RIGHT;
+
+  return CENTER;
+}
+
+/** We don't know about the melisma until after the initial alignment work is done, so go
+    back and fix the alignment when we DO know.
+*/
+void
+Syllable_group::adjust_melisma_align()
+{
+  if(notehead_l_ && lyric_list_.size()) {
+    // override any previous offset adjustments
+    Real translation = -group_translation_f_;
+    // melisma aligning:
+    switch (alignment_i_) {
+      //  case LEFT: // that's all
+    case CENTER: // move right so smallest lyric is left-aligned on notehead
+      translation += (shortest_lyric_l_->extent(X_AXIS)).length()/2;
+      break;
+    case RIGHT: // move right so smallest lyric is left-aligned on notehead
+      translation += (shortest_lyric_l_->extent(X_AXIS)).length();
+      break;
+    }
+    group_translation_f_ += translation;
+    for(int l = 0; l < lyric_list_.size(); l++) {
+      lyric_list_[l]->translate_axis (translation, X_AXIS);
+    }
+  }
+}
+
+
+bool
+Syllable_group::is_empty()
+{
+  return lyric_list_.size()==0;
+}
+
+void
+Syllable_group::next_lyric()
+{
+  first_in_phrase_b_ = (alignment_i_ == RIGHT);
+  clear();
+}
+
+/* SMOB */
+SCM
+Syllable_group::mark_smob (SCM)
+{
+  return SCM_EOL;
+}
+
+int
+Syllable_group::print_smob (SCM, SCM port, scm_print_state * )
+{
+  scm_puts ("#<Syllable_group>", port);
+  return 1;
+}
+
+IMPLEMENT_UNSMOB(Syllable_group, voice_entry);
+IMPLEMENT_SIMPLE_SMOBS(Syllable_group);
+IMPLEMENT_DEFAULT_EQUAL_P(Syllable_group);
+
+SCM
+Syllable_group::make_entry ()
+{
+  Syllable_group *vi = new Syllable_group;
+  return vi->smobbed_self ();
+}
index 8d92fb8ac15b9d7d528923ffe7b695cec7751f1b..d2b7c83a04dbcd637bdf31ac8ab7759d81a9ed23 100644 (file)
 Translator_group::Translator_group (Translator_group const&s)
   : Translator(s)
 {
-  consists_str_arr_ = s.consists_str_arr_;
-  consists_end_str_arr_ = s.consists_end_str_arr_;
-  accepts_str_arr_ = s.accepts_str_arr_;
   iterator_count_ =0;
-  properties_dict_ = new Scheme_hash_table (*s.properties_dict_);
+  
+  Scheme_hash_table * tab =  new Scheme_hash_table (*s.properties_dict ());
+  properties_scm_ = tab->self_scm ();
+  scm_unprotect_object (tab->self_scm( ));
+}
+
+Scheme_hash_table*
+Translator_group::properties_dict () const
+{
+  return Scheme_hash_table::unsmob (properties_scm_);
 }
 
 Translator_group::~Translator_group ()
 {
   assert (removable_b());
-  trans_p_list_.junk ();
-  scm_unprotect_object (properties_dict_->self_scm ());
 }
 
 
 Translator_group::Translator_group()
 {
   iterator_count_  = 0;
-  properties_dict_ = new Scheme_hash_table ;
+  Scheme_hash_table *tab = new Scheme_hash_table ;
+  properties_scm_ = tab->self_scm ();
+
+  scm_unprotect_object (tab->self_scm ());
 }
 
 void
 Translator_group::check_removal()
 {
-  Cons<Translator> *next =0;
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = next)
+  SCM next = SCM_EOL; 
+  for (SCM p = trans_group_list_; gh_pair_p (p); p = next)
     {
-      next = p->next_;
-      if (Translator_group *trg =  dynamic_cast <Translator_group *> (p->car_))
-       {
-         trg->check_removal ();
-         if (trg->removable_b())
-           terminate_translator (trg);
-       }
+      next = gh_cdr (p);
+
+      Translator_group *trg =  dynamic_cast<Translator_group*> (unsmob_translator (gh_car (p)));
+
+      trg->check_removal ();
+      if (trg->removable_b())
+       terminate_translator (trg);
     }
 }
 
-void
-Translator_group::add_translator (Translator *trans_p)
+
+SCM
+Translator_group::add_translator (SCM list, Translator *t)
 {
-  trans_p_list_.append (new Killing_cons<Translator> (trans_p,0));
+  list = gh_append2 (list, gh_cons (t->self_scm (), SCM_EOL));
+  t->daddy_trans_l_ = this;
+  t->output_def_l_ = output_def_l_;
+  t->add_processing ();
 
-  trans_p->daddy_trans_l_ = this;
-  trans_p->output_def_l_ = output_def_l_;
-  trans_p->add_processing ();
+  return list;
 }
-
 void
-Translator_group::set_acceptor (String accepts, bool add)
+Translator_group::add_simple_translator (Translator*t)
 {
-  if (add)
-    accepts_str_arr_.push (accepts);
-  else
-    for (int i=accepts_str_arr_.size (); i--; )
-      if (accepts_str_arr_[i] == accepts)
-       accepts_str_arr_.del (i);
+  simple_trans_list_ = add_translator (simple_trans_list_, t);
 }
-
 void
-Translator_group::add_last_element (String s)
+Translator_group::add_group_translator (Translator *t)
 {
-  if (!get_translator_l (s))
-    error (_ ("Program has no such type"));
-
-  for (int i=consists_end_str_arr_.size (); i--; )
-    if (consists_end_str_arr_[i] == s)
-      warning (_f ("Already contains: `%s'", s));
-      
-  consists_end_str_arr_.push (s);
+  trans_group_list_ = add_translator (trans_group_list_,t);
 }
 
-void
-Translator_group::set_element (String s, bool add)
-{
-  if (!get_translator_l (s))
-    error (_ ("Program has no such type"));
 
-  if (add)
-    {
-      for (int i=consists_str_arr_.size (); i--; )
-       if (consists_str_arr_[i] == s)
-         warning (_f("Already contains: `%s'", s));
-      
-      consists_str_arr_.push (s);
-    }
-  else
-    {
-      for (int i=consists_str_arr_.size (); i--; )
-       if (consists_str_arr_[i] == s)
-         consists_str_arr_.del (i);
-      for (int i=consists_end_str_arr_.size (); i--; )
-       if (consists_end_str_arr_[i] == s)
-         consists_end_str_arr_.del (i);
-    }
-}
+
 bool
 Translator_group::removable_b() const
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-    {
-      if (dynamic_cast <Translator_group *> (p->car_))
-       return false;
-    }
-
-  return !iterator_count_;
+  return trans_group_list_ == SCM_EOL && ! iterator_count_;
 }
 
 Translator_group *
@@ -131,10 +98,11 @@ Translator_group::find_existing_translator_l (String n, String id)
     return this;
 
   Translator_group* r = 0;
-  for (Cons<Translator> *p = trans_p_list_.head_; !r && p; p = p->next_)
+  for (SCM p = trans_group_list_; !r && gh_pair_p (p); p = gh_cdr (p))
     {
-      if (Translator_group *trg =  dynamic_cast <Translator_group *> (p->car_))
-       r = trg->find_existing_translator_l (n, id);
+      Translator *  t = unsmob_translator (gh_car (p));
+      
+      r = dynamic_cast<Translator_group*> (t)->find_existing_translator_l (n, id);
     }
 
   return r;
@@ -143,10 +111,11 @@ Translator_group::find_existing_translator_l (String n, String id)
 Link_array<Translator_group>
 Translator_group::path_to_acceptable_translator (String type, Music_output_def* odef) const
 {
- Link_array<Translator_group> accepted_arr;
-  for (int i=0; i < accepts_str_arr_.size (); i++)
 Link_array<Translator_group> accepted_arr;
+  for (SCM s = accepts_name_list_; gh_pair_p (s); s = gh_cdr (s))
     {
-      Translator *t = odef->find_translator_l (accepts_str_arr_[i]);
+      
+      Translator *t = odef->find_translator_l (ly_scm2string (gh_car (s)));
       if (!t || !dynamic_cast <Translator_group *> (t))
        continue;
       accepted_arr.push (dynamic_cast <Translator_group *> (t));
@@ -198,7 +167,7 @@ Translator_group::find_create_translator_l (String n, String id)
        {
          Translator_group * new_group = dynamic_cast<Translator_group*>(path[i]->clone ());
 
-         current->add_translator (new_group);
+         current->add_group_translator (new_group);
          current = new_group;
        }
       current->id_str_ = id;
@@ -221,12 +190,10 @@ Translator_group::try_music_on_nongroup_children (Music *m)
 {
   bool hebbes_b =false;
 
-  for (Cons<Translator> *p = trans_p_list_.head_; !hebbes_b && p; p = p->next_)
+  
+  for (SCM p = simple_trans_list_; !hebbes_b && gh_pair_p (p); p = gh_cdr (p))
     {
-      if (!dynamic_cast <Translator_group *> (p->car_))
-       {
-         hebbes_b = p->car_->try_music (m);
-       }
+      hebbes_b = unsmob_translator (gh_car (p))->try_music (m);
     }
   return hebbes_b;
 }
@@ -256,17 +223,14 @@ Translator_group::ancestor_l (int level)
   return daddy_trans_l_->ancestor_l (level-1);
 }
 
-
-
-
-
 void
 Translator_group::terminate_translator (Translator*r_l)
 {
   r_l->removal_processing();
   Translator * trans_p =remove_translator_p (r_l);
-
-  delete trans_p;
+  /*
+    forget trans_p, GC does the rest.
+   */
 }
 
 
@@ -277,28 +241,20 @@ Translator *
 Translator_group::remove_translator_p (Translator*trans_l)
 {
   assert (trans_l);
-  
-  for (Cons<Translator> **pp = &trans_p_list_.head_; *pp; pp = &(*pp)->next_)
-    if ((*pp)->car_ == trans_l)
-      {
-       Cons<Translator> *r = trans_p_list_.remove_cons (pp);
-       r->car_ =0;
-       trans_l->daddy_trans_l_ =0;
-       delete r;
-       return trans_l;
-      }
 
-  return 0;
+  trans_group_list_ = scm_delq_x (trans_l->self_scm (), trans_group_list_);
+  trans_l->daddy_trans_l_ = 0;
+  return trans_l;
 }
 
 
 Translator*
 Translator_group::get_simple_translator (String type) const
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
+  for (SCM p = simple_trans_list_;  gh_pair_p (p); p =gh_cdr (p))
     {
-      if (classname (p->car_) == type)
-       return p->car_;
+      if (classname (unsmob_translator (gh_car (p))) == type)
+       return unsmob_translator (gh_car (p));
     }
   if (daddy_trans_l_)
     return daddy_trans_l_->get_simple_translator (type);
@@ -309,7 +265,7 @@ Translator_group::get_simple_translator (String type) const
 bool
 Translator_group::is_bottom_translator_b () const
 {
-  return !accepts_str_arr_.size ();
+  return accepts_name_list_ == SCM_EOL;
 }
 
 
@@ -317,16 +273,17 @@ Translator_group::is_bottom_translator_b () const
 Translator_group*
 Translator_group::get_default_interpreter()
 {
-  if (accepts_str_arr_.size())
+  if (gh_pair_p (accepts_name_list_))
     {
-      Translator*t = output_def_l ()->find_translator_l (accepts_str_arr_[0]);
+      String str = ly_scm2string (gh_car (accepts_name_list_));
+      Translator*t = output_def_l ()->find_translator_l (str);
       if (!t)
        {
-         warning (_f ("can't find or create: `%s'", accepts_str_arr_[0]));
+         warning (_f ("can't find or create: `%s'", str));
          t = this;
        }
       Translator_group * g= dynamic_cast <Translator_group*>(t->clone ());
-      add_translator (g);
+      add_group_translator (g);
 
       if (!g->is_bottom_translator_b ())
        return g->get_default_interpreter ();
@@ -336,105 +293,90 @@ Translator_group::get_default_interpreter()
   return this;
 }
 
-void
-Translator_group::each (Method_pointer method)
+static void
+static_each (SCM list, Method_pointer method)
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-    (p->car_->*method) ();
+  for (SCM p = list; gh_pair_p (p); p = gh_cdr(p))
+    (unsmob_translator (gh_car (p))->*method) ();
+  
 }
 
-
 void
-Translator_group::each (Const_method_pointer method) const
+Translator_group::each (Method_pointer method) 
 {
-  for (Cons<Translator> *p = trans_p_list_.head_; p; p = p->next_)
-    (p->car_->*method) ();
+  static_each (simple_trans_list_, method);
+  static_each (trans_group_list_, method);
 }
 
 void
 Translator_group::do_print() const
 {
 #ifndef NPRINT
-  if (!flower_dstream)
-    return ;
-
-  gh_display (properties_dict_->self_scm ());
-  if (status == ORPHAN)
-    {
-      DEBUG_OUT << "consists of: ";
-      for (int i=0; i < consists_str_arr_.size (); i++)
-       DEBUG_OUT << consists_str_arr_[i] << ", ";
-      DEBUG_OUT << "\naccepts: ";
-      for (int i=0; i < accepts_str_arr_.size (); i++)
-       DEBUG_OUT << accepts_str_arr_[i] << ", ";
-    }
-  else
-    {
-      if (id_str_.length_i ())
-       DEBUG_OUT << "ID: " << id_str_ ;
-      DEBUG_OUT << " iterators: " << iterator_count_<< '\n';
-    }
-  each (&Translator::print);
 #endif
 }
 
-void
-Translator_group::do_pre_move_processing ()
+static SCM
+trans_list (SCM namelist, Music_output_def *mdef)
 {
-  each (&Translator::pre_move_processing);
-}
-
-void
-Translator_group::do_post_move_processing ()
-{
-  each (&Translator::post_move_processing);
-}
-
-void
-Translator_group::do_process_music ()
-{
-  each (&Translator::process_music);
-}
-
-void
-Translator_group::do_creation_processing ()
-{
-  each (&Translator::creation_processing);
+  SCM l = SCM_EOL;
+  for (SCM s = namelist; gh_pair_p (s) ; s = gh_cdr (s))
+    {
+      Translator * t = mdef->find_translator_l (ly_scm2string (gh_car (s)));
+      if (!t)
+       warning (_f ("can't find: `%s'", s));
+      else
+       {
+         Translator * tr = t->clone ();
+         SCM str = tr->self_scm ();
+         l = gh_cons (str, l);
+         scm_unprotect_object (str);
+       }
+    }
+  return l; 
 }
 
-void
-Translator_group::do_removal_processing ()
-{
-  each (&Translator::removal_processing);
-}
 
 void
 Translator_group::do_add_processing ()
 {
-   for (int i=0; i < consists_str_arr_.size(); i++)
+  assert (simple_trans_list_== SCM_EOL);
+
+  SCM correct_order = scm_reverse (property_pushes_); // pity of the mem.
+  for (SCM s = correct_order; gh_pair_p (s); s = gh_cdr (s))
     {
-      String s = consists_str_arr_[i];
-      Translator * t = output_def_l ()->find_translator_l (s);
-      if (!t)
-       warning (_f ("can't find: `%s'", s));
-      else
-       add_translator (t->clone ());
+      SCM entry = gh_car (s);
+      SCM val = gh_cddr (entry);
+      val = gh_pair_p (val) ? gh_car (val) : SCM_UNDEFINED;
+      
+      Translator_group_initializer::apply_pushpop_property (this, gh_car (entry),
+                                                           gh_cadr (entry),
+                                                           val);
     }
-   for (int i=0; i-- < consists_end_str_arr_.size (); i++)
-     {
-       String s = consists_end_str_arr_[i];
-       Translator * t = output_def_l ()->find_translator_l (s);
-       if (!t)
-        warning (_f ("can't find: `%s'", s));
-       else
-        add_translator (t->clone ());
+
+  SCM l1 = trans_list (consists_name_list_, output_def_l ());
+  SCM l2 =trans_list (end_consists_name_list_, output_def_l ());
+  l1 = scm_reverse_x (l1, l2);
+  
+  simple_trans_list_ = l1;
+  for (SCM s = l1; gh_pair_p (s) ; s = gh_cdr (s))
+    {
+      Translator * t = unsmob_translator (gh_car (s));
+
+      t->daddy_trans_l_ = this;
+      t->output_def_l_ = output_def_l_;
+      t->add_processing ();
     }
+
+  
 }
 
+/*
+  PROPERTIES
+ */
 Translator_group*
 Translator_group::where_defined (SCM sym) const
 {
-  if (properties_dict_->elem_b (sym))
+  if (properties_dict ()->elem_b (sym))
     {
       return (Translator_group*)this;
     }
@@ -445,9 +387,9 @@ Translator_group::where_defined (SCM sym) const
 SCM
 Translator_group::get_property (SCM sym) const
 {
-  if (properties_dict_->elem_b (sym))
+  if (properties_dict ()->elem_b (sym))
     {
-      return properties_dict_->get (sym);
+      return properties_dict ()->get (sym);
     }
 
   if (daddy_trans_l_)
@@ -465,7 +407,78 @@ Translator_group::set_property (String id, SCM val)
 void
 Translator_group::set_property (SCM sym, SCM val)
 {
-  properties_dict_->set (sym, val);
+  properties_dict ()->set (sym, val);
 }
 
+/*
+  Push or pop (depending on value of VAL) a single entry (ELTPROP . VAL)
+  entry from a translator property list by name of PROP
+*/
+void
+Translator_group::execute_single_pushpop_property (SCM prop, SCM eltprop, SCM val)
+{
+  if (gh_symbol_p(prop))
+    {
+      if (val != SCM_UNDEFINED)
+       {
+         SCM prev = get_property (prop);
 
+         prev = gh_cons (gh_cons (eltprop, val), prev);
+         set_property (prop, prev);
+       }
+      else
+       {
+         SCM prev = get_property (prop);
+
+         SCM newprops= SCM_EOL ;
+         while (gh_pair_p (prev) && gh_caar (prev) != eltprop)
+           {
+             newprops = gh_cons (gh_car (prev), newprops);
+             prev = gh_cdr (prev);
+           }
+         
+         if (gh_pair_p (prev))
+           {
+             newprops = scm_reverse_x (newprops, gh_cdr (prev));
+             set_property (prop, newprops);
+           }
+       }
+    }
+}
+
+
+
+
+
+/*
+  STUBS
+*/
+void
+Translator_group::do_pre_move_processing ()
+{
+  each (&Translator::pre_move_processing);
+}
+
+void
+Translator_group::do_post_move_processing ()
+{
+  each (&Translator::post_move_processing);
+}
+
+void
+Translator_group::do_process_music ()
+{
+  each (&Translator::process_music);
+}
+
+void
+Translator_group::do_creation_processing ()
+{
+  each (&Translator::creation_processing);
+}
+
+void
+Translator_group::do_removal_processing ()
+{
+  each (&Translator::removal_processing);
+}
index 68db603831d8396abbec3acb0d4955e63980b68c..6605eaae0ca1ae2ababd353a41ede4b9fa856f95 100644 (file)
@@ -12,6 +12,7 @@
 #include "translator-group.hh"
 
 #include "moment.hh"
+#include "ly-smobs.icc"
 
 char const*
 Translator::name() const
@@ -23,20 +24,42 @@ Translator::~Translator ()
 {
 }
 
+void
+Translator::init ()
+{
+  status_ = ORPHAN;
+  simple_trans_list_ = SCM_EOL;
+  trans_group_list_ = SCM_EOL;
+  properties_scm_ = SCM_EOL;
+  accepts_name_list_ = SCM_EOL;   
+  consists_name_list_ = SCM_EOL;
+  end_consists_name_list_ = SCM_EOL;
+  property_pushes_ = SCM_EOL;
+  daddy_trans_l_ =0;
+}
+
 Translator::Translator ()
 {
-  status = ORPHAN;
-  daddy_trans_l_ = 0;
+  init ();
   output_def_l_ = 0;
+  smobify_self ();
+
 }
 
 Translator::Translator (Translator const &s)
   : Input (s)
 {
-  status = ORPHAN;
-  daddy_trans_l_ =0;
+  init ();
+  
+  consists_name_list_ = scm_list_copy (s.consists_name_list_);
+  end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
+  accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
+  property_pushes_ = scm_list_copy (s.property_pushes_);
+  
   output_def_l_ = s.output_def_l_;
   type_str_ = s.type_str_;
+
+  smobify_self ();
 }
 
 bool
@@ -62,11 +85,11 @@ Translator::now_mom () const
 void
 Translator::add_processing ()
 {
-  if (status > ORPHAN)
+  if (status_ > ORPHAN)
     return;
   
   do_add_processing ();
-  status = VIRGIN;
+  status_ = VIRGIN;
 }
 
 void
@@ -97,40 +120,40 @@ Translator::do_print () const
 void
 Translator::creation_processing ()
 {
-  if (status >= CREATION_INITED)
+  if (status_ >= CREATION_INITED)
     return ;
   
   do_creation_processing ();
-  status = CREATION_INITED;
+  status_ = CREATION_INITED;
 }
 
 void
 Translator::post_move_processing ()
 {
-  if (status >= MOVE_INITED)
+  if (status_ >= MOVE_INITED)
     return;
 
   creation_processing ();
   do_post_move_processing ();
-  status = MOVE_INITED;
+  status_ = MOVE_INITED;
 }
 
 void
 Translator::removal_processing ()
 {
-  if (status == ORPHAN)
+  if (status_ == ORPHAN)
     return;
   creation_processing ();
   do_removal_processing ();
   // elegancy ...
-  // status = ORPHAN;
+  // status_ = ORPHAN;
 }
 
 
 bool
 Translator::try_music (Music * r)
 {
-  if (status < MOVE_INITED)
+  if (status_ < MOVE_INITED)
     post_move_processing ();
 
   return do_try_music (r);
@@ -139,12 +162,12 @@ Translator::try_music (Music * r)
 void
 Translator::process_music ()
 {
-  if (status < PROCESSED_REQS)
+  if (status_ < PROCESSED_REQS)
     post_move_processing ();
-  else if (status >= PROCESSED_REQS)
+  else if (status_ >= PROCESSED_REQS)
     return; 
   
-  status = PROCESSED_REQS;
+  status_ = PROCESSED_REQS;
   do_process_music ();
 }
 
@@ -152,7 +175,7 @@ void
 Translator::pre_move_processing ()
 {
   do_pre_move_processing ();
-  status = CREATION_INITED;
+  status_ = CREATION_INITED;
 }
 
 
@@ -199,3 +222,47 @@ void
 Translator::do_removal_processing ()
 {
 }
+
+
+/*
+
+  SMOBS
+
+*/
+SCM
+Translator::mark_smob (SCM sm)
+{
+  Translator * me = (Translator*) SCM_CELL_WORD_1(sm);
+  scm_gc_mark (me->consists_name_list_);
+  scm_gc_mark (me->accepts_name_list_);
+  scm_gc_mark (me->end_consists_name_list_);
+  scm_gc_mark (me->simple_trans_list_);
+  scm_gc_mark (me->trans_group_list_);
+  scm_gc_mark (me->property_pushes_);
+  return me->properties_scm_;
+}
+
+
+int
+Translator::print_smob (SCM s, SCM port, scm_print_state *)
+{
+  Translator *sc = (Translator *) gh_cdr (s);
+     
+  scm_puts ("#<Translator ", port);
+  scm_puts ((char *)sc->name (), port);
+  scm_display (sc->simple_trans_list_, port);
+  /*
+    don't try to print properties, that is too much hassle.
+   */
+  scm_puts (" >", port);
+
+  
+  
+  return 1;
+}
+
+
+
+IMPLEMENT_UNSMOB(Translator, translator);
+IMPLEMENT_SMOBS(Translator);
+IMPLEMENT_DEFAULT_EQUAL_P(Translator);
index ed5e782706b56c44820057833212bcfccff4ec24..a6684ed45416fa1fccf517d3f06eba82daa19e81 100644 (file)
@@ -22,30 +22,27 @@ protected:
 
 ADD_THIS_TRANSLATOR (Voice_devnull_engraver);
 
+static char const *junk_interfaces[] = {
+  //   "beam-interface",
+  "slur-interface",
+  "tie-interface",
+  "text-item-interface",
+  "text-script-interface",
+  "dynamic-interface",
+  "crescendo-interface",
+  0
+};
+
 void
 Voice_devnull_engraver::acknowledge_element (Score_element_info i)
 {
   if (daddy_trans_l_->id_str_ == "two"
       && (to_boolean (get_property ("unison"))
          || to_boolean (get_property ("unisilence"))))
-    {
-      static char const *junk[] = {
-       //      "beam-interface",
-       "slur-interface",
-       "tie-interface",
-       "text-item-interface",
-       "text-script-interface",
-       "dynamic-interface",
-       "crescendo-interface",
-       0
-      };
-      for (char const **p = junk; *p; *p++)
+    for (char const **p = junk_interfaces; *p; p++)
+      if (i.elem_l_->has_interface (ly_symbol2scm (*p)))
        {
-         if (i.elem_l_->has_interface (ly_symbol2scm (*p)))
-           {
-             i.elem_l_->suicide ();
-             return;
-           }
+         i.elem_l_->suicide ();
+         return;
        }
-    }
 }
index 5116a7904fb3587c11d8e7074eb699a382f05083..70285815a7fbb99d176e43f96f7b68e9f8b584eb 100644 (file)
    )
 
 ;; The regex module may not be available, or may be broken.
-(define use-regex
+(define chord-use-regex
   (let ((os (string-downcase (vector-ref (uname) 0))))
     (not (equal? "cygwin" (substring os 0 (min 6 (string-length os)))))))
 
+;; If you have trouble with regex, define #f
+(define chord-use-regex #t)
+;;(define chord-use-regex #f)
+
 ;;
 ;; (octave notename accidental)
 ;;
     (apply append (pitch->text-banter tonic)
           (if user-name user-name '())
           ;; why does list->string not work, format seems only hope...
-          (if (and use-regex
+          (if (and chord-use-regex
                    (string-match "super" (format "~s" user-name))
                    (or (pair? additions)
                        (pair? subtractions)))
index a786acd0a18c9bc158b30f4c1d5daa6f793336ac..befcda71bce6c7355f507973609a3fe5f7d884c8 100644 (file)
 
 (define generic-All-properties
   (cons 'all
-       (list (list 'fontSize number? 'fontsize))))
+       (list (list 'fontSize number? 'font-size))))
 
 
 (define generic-notehead-properties
index 13f8359c55e5d513d0cb7ea935a30a3b17bc0b10..147f5b58503e94433432cca322b630fa225b376e 100644 (file)
 (use-modules (ice-9 regex))
 
 ;; The regex module may not be available, or may be broken.
-;; If you have trouble with regex, define #f
-;;(define use-regex #t)
-;;(define use-regex #f)
-
 (define use-regex
   (let ((os (string-downcase (vector-ref (uname) 0))))
     (not (equal? "cygwin" (substring os 0 (min 6 (string-length os)))))))
 
+;; If you have trouble with regex, define #f
+(define use-regex #t)
+;;(define use-regex #f)
+
 ;; do nothing in .scm output
 (define (comment s) "")
 
index e592f9f38fa5756dd878f11216be5d63d047cf2e..cc0d03c07ef07e94ba710aad9f4c351d55a5679f 100644 (file)
@@ -1049,12 +1049,15 @@ def help ():
        print r"""
 Convert ABC to Mudela.
 
-Usage: abc2ly [OPTION]... ABC-FILE
+Usage: abc2ly [OPTIONS]... ABC-FILE
 
 Options:
   -h, --help          this help
   -o, --output=FILE   set output filename to FILE
   -v, --version       version information
+
+This program converts ABC music files (see
+http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) To LilyPond input.
 """
 
 def print_version ():
index 6bca70dc7739e4e541628c7ac47692d1c631b888..d1220794a6556252cd1e021bd4316df0149ef426 100644 (file)
@@ -1,3 +1,5 @@
+dnl WARNING WARNING WARNING WARNING
+dnl do not edit! this is aclocal.m4, generated from stepmake/aclocal.m4
 dnl aclocal.m4   -*-shell-script-*-
 dnl StepMake subroutines for configure.in
 
@@ -646,20 +648,24 @@ AC_DEFUN(AC_STEPMAKE_TEXMF, [
            break;
        fi
     done
+    AC_MSG_RESULT($MFMODE)
 
+    AC_MSG_CHECKING(for mfplain.mp)
     #
     # For now let people define these in their environments
     #
     : ${MFPLAIN_MP=`kpsewhich mp mfplain.mp`}
+    AC_MSG_RESULT($MFPLAIN_MP)
 
+    AC_MSG_CHECKING(for inimetapost flags)
     if test  ${INIMETAPOST} = "inimp" ; then
        : ${INIMETAPOST_FLAGS=''}
     else
        : ${INIMETAPOST_FLAGS='-interaction=nonstopmode'}
     fi
+    AC_MSG_RESULT($INIMETAPOST_FLAGS)
 
     rm -f mfput.*
-    AC_MSG_RESULT($MFMODE)
 
     AC_SUBST(METAFONT)
     AC_SUBST(METAPOST)