From 4a490013bf77bd48a12f23ae1b13739dd93f337a Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Thu, 12 Sep 2002 22:26:20 +0000 Subject: [PATCH] * lily/property-iterator.cc (do_quit): add finalization functions to undo property settings. * lily/parser.yy (property_def): syntax for \once \property .... * lily/note-spacing.cc (get_spacing): don't get crazy when there is no (live) stem. * lily/my-lily-lexer.cc: new keyword \once * lily/global-translator.cc (apply_finalizations): new function (add_finalization): new function --- lily/engraver.cc | 12 +----- lily/global-translator.cc | 40 +++++++++++++++-- lily/include/global-translator.hh | 7 ++- lily/include/property-iterator.hh | 9 ++-- lily/include/translator.hh | 2 + lily/my-lily-lexer.cc | 1 + lily/note-spacing.cc | 9 +++- lily/parser.yy | 18 ++++++-- lily/property-iterator.cc | 71 +++++++++++++++++++++++++++++-- lily/score-engraver.cc | 6 +-- lily/sequential-iterator.cc | 3 +- 11 files changed, 145 insertions(+), 33 deletions(-) diff --git a/lily/engraver.cc b/lily/engraver.cc index 02bf0e1074..b8cb0f4939 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -68,17 +68,7 @@ Engraver::Engraver() Score_engraver* Engraver::top_engraver () const { - /* - ugh. - */ - if (dynamic_cast((Engraver*)this)) - return dynamic_cast ((Engraver*)this); - - if (daddy_trans_) - return dynamic_cast (daddy_trans_)->top_engraver (); - - programming_error ("No score engraver!"); - return 0; + return dynamic_cast (top_translator()); } ENTER_DESCRIPTION(Engraver, diff --git a/lily/global-translator.cc b/lily/global-translator.cc index 0c079c40d2..bbe997ce0b 100644 --- a/lily/global-translator.cc +++ b/lily/global-translator.cc @@ -72,6 +72,7 @@ void Global_translator::one_time_step () { } + void Global_translator::start () { @@ -100,9 +101,6 @@ Global_translator::run_iterator_on_me (Music_iterator * iter) w = sneaky_insert_extra_moment (w); // printf ("proccing %s\n ", w.string ().to_str0 ()); - - - if (first) { first = false; @@ -116,3 +114,39 @@ Global_translator::run_iterator_on_me (Music_iterator * iter) one_time_step (); } } + +void +Global_translator::apply_finalizations () +{ + SCM lst = get_property ("finalizations"); + set_property ("finalizations" , SCM_EOL); + for (SCM s = lst ; gh_pair_p (s); s = gh_cdr (s)) + { + scm_primitive_eval (gh_car (s)); + } +} + +/* + Add a function to execute before stepping to the next time step. + */ +void +Global_translator::add_finalization (SCM x) +{ + SCM lst = get_property ("finalizations"); + lst = scm_cons (x, lst); + set_property ("finalizations" ,lst); +} + + +Global_translator * +Translator::top_translator()const +{ + if (dynamic_cast((Translator*)this)) + return dynamic_cast ((Translator*)this); + + if (daddy_trans_) + return daddy_trans_->top_translator (); + + programming_error ("No top translator!"); + return 0; +} diff --git a/lily/include/global-translator.hh b/lily/include/global-translator.hh index c59cc3fb43..39d814747c 100644 --- a/lily/include/global-translator.hh +++ b/lily/include/global-translator.hh @@ -14,8 +14,8 @@ #include "moment.hh" #include "pqueue.hh" - -class Global_translator : public virtual Translator_group{ +class Global_translator : public virtual Translator_group +{ PQueue extra_mom_pq_; public: VIRTUAL_COPY_CONS (Translator); @@ -28,6 +28,9 @@ public: Moment sneaky_insert_extra_moment (Moment); void add_moment_to_process (Moment); void run_iterator_on_me (Music_iterator*); + + void apply_finalizations (); + void add_finalization (SCM); virtual Music_output *get_output (); virtual void prepare (Moment); diff --git a/lily/include/property-iterator.hh b/lily/include/property-iterator.hh index c7c3cc5cda..50485ed15c 100644 --- a/lily/include/property-iterator.hh +++ b/lily/include/property-iterator.hh @@ -23,8 +23,10 @@ class Property_iterator : public Simple_music_iterator public: VIRTUAL_COPY_CONS (Music_iterator); DECLARE_SCHEME_CALLBACK(constructor, ()); - /* construction */ + DECLARE_SCHEME_CALLBACK(once_finalization, (SCM, SCM )); + protected: + virtual void do_quit(); virtual void process (Moment); }; @@ -39,7 +41,6 @@ class Property_unset_iterator : public Simple_music_iterator public: VIRTUAL_COPY_CONS (Music_iterator); DECLARE_SCHEME_CALLBACK(constructor, ()); - /* construction */ protected: virtual void process (Moment); }; @@ -49,9 +50,10 @@ class Push_property_iterator : public Simple_music_iterator public: VIRTUAL_COPY_CONS (Music_iterator); DECLARE_SCHEME_CALLBACK(constructor, ()); + DECLARE_SCHEME_CALLBACK(once_finalization, (SCM, SCM)); protected: - /* construction */ virtual void process (Moment); + virtual void do_quit(); }; class Pop_property_iterator : public Simple_music_iterator @@ -60,7 +62,6 @@ public: DECLARE_SCHEME_CALLBACK(constructor, ()); VIRTUAL_COPY_CONS (Music_iterator); protected: - /* construction */ virtual void process (Moment); }; diff --git a/lily/include/translator.hh b/lily/include/translator.hh index 97784a82a9..4b27559aa9 100644 --- a/lily/include/translator.hh +++ b/lily/include/translator.hh @@ -66,7 +66,9 @@ public: SCM properties_scm_; DECLARE_SMOBS (Translator, dummy); + public: + Global_translator * top_translator () const; TRANSLATOR_DECLARATIONS(Translator); /** try to fit the request in this engraver diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index cff5ae13e6..48005225d1 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -58,6 +58,7 @@ static Keyword_ent the_key_tab[]={ {"lyrics", LYRICS}, {"key", KEY}, {"mark", MARK}, + {"once", ONCE}, {"pitch", PITCH}, {"time", TIME_T}, {"times", TIMES}, diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index e7256e8bbe..7964a2966e 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -66,6 +66,10 @@ Note_spacing::get_spacing (Grob *me, Item* right_col, if (!g) g = Note_column::first_head (it); + /* + Ugh. If Stem is switched off, we don't know what the + first note head will be. + */ if (g) left_head_wid = g->extent(it_col, X_AXIS); } @@ -102,7 +106,8 @@ Note_spacing::get_spacing (Grob *me, Item* right_col, */ *fixed = left_head_wid.empty_b () ? increment : left_head_wid[RIGHT]; *space = (base_space - increment) + *fixed + - (extents[LEFT][RIGHT] - left_head_wid[RIGHT])/ 2; + (extents[LEFT][RIGHT] + - (left_head_wid.empty_b () ? 0.0 : left_head_wid[RIGHT]))/ 2; ; if (*space - *fixed < 2 * ((- extents[RIGHT][LEFT]) >? 0)) @@ -233,7 +238,7 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, Grob *stem = Note_column::get_stem (it); - if (!stem) + if (!stem || !stem->live ()) { if (d == RIGHT && Separation_item::has_interface (it)) { diff --git a/lily/parser.yy b/lily/parser.yy index 450fa77c5f..99ff663353 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -210,6 +210,7 @@ yylex (YYSTYPE *s, void * v) %token NAME %token PITCHNAMES %token NOTES +%token ONCE %token PAPER %token PARTIAL %token PENALTY @@ -283,7 +284,6 @@ yylex (YYSTYPE *s, void * v) %type tremolo_type %type bare_int bare_unsigned %type script_dir - %type identifier_init %type steno_duration optional_notemode_duration multiplied_duration @@ -302,7 +302,7 @@ yylex (YYSTYPE *s, void * v) %type embedded_scm scalar %type Music Sequential_music Simultaneous_music %type relative_music re_rhythmed_music part_combined_music -%type property_def translator_change +%type property_def translator_change simple_property_def %type Music_list %type music_output_def_body %type shorthand_command_req @@ -1038,6 +1038,15 @@ translator_change: ; property_def: + simple_property_def + | ONCE simple_property_def { + $$ = $2; + SCM e = $2->get_mus_property ("element"); + unsmob_music (e)->set_mus_property ("once", SCM_BOOL_T); + } + ; + +simple_property_def: PROPERTY STRING '.' STRING '=' scalar { Music *t = set_property_music (scm_string_to_symbol ($4), $6); @@ -1090,7 +1099,9 @@ property_def: csm-> set_mus_property ("context-type", $2); } - | PROPERTY STRING '.' STRING OVERRIDE embedded_scm '=' embedded_scm { + | PROPERTY STRING '.' STRING OVERRIDE + embedded_scm '=' embedded_scm + { /* UGH UGH UGH UGH. */ @@ -1118,6 +1129,7 @@ property_def: $$->set_spot (THIS->here_input ()); csm-> set_mus_property ("context-type", $2); + } | PROPERTY STRING '.' STRING REVERT embedded_scm { Music *t = new Music (SCM_EOL); diff --git a/lily/property-iterator.cc b/lily/property-iterator.cc index 480b506858..cf018f4f2a 100644 --- a/lily/property-iterator.cc +++ b/lily/property-iterator.cc @@ -10,6 +10,7 @@ #include "music.hh" #include "translator-def.hh" #include "translator-group.hh" +#include "global-translator.hh" bool check_grob(Music *mus, SCM sym); @@ -44,6 +45,34 @@ Property_unset_iterator::process (Moment m) Simple_music_iterator::process (m); } +MAKE_SCHEME_CALLBACK(Property_iterator,once_finalization, 2); +SCM +Property_iterator::once_finalization(SCM translator, SCM music ) +{ + Music * m = unsmob_music (music); + Translator_group * tg + = dynamic_cast (unsmob_translator (translator)); + SCM sym = m->get_mus_property ("symbol"); + + tg->unset_property (sym); + return SCM_UNSPECIFIED; +} + +void +Property_iterator::do_quit () +{ + if (to_boolean (get_music ()->get_mus_property ("once"))) + { + SCM trans = report_to()->self_scm(); + SCM music = get_music()->self_scm(); + + Global_translator * tg= report_to()->top_translator (); + + tg->add_finalization (scm_list_n (once_finalization_proc, + trans, music, SCM_UNDEFINED)); + } +} + SCM list_p = 0; @@ -75,13 +104,47 @@ Push_property_iterator::process (Moment m) SCM eprop = get_music ()->get_mus_property ("grob-property"); SCM val = get_music ()->get_mus_property ("grob-value"); - if (to_boolean (get_music ()->get_mus_property ("pop-first"))) + if (to_boolean (get_music ()->get_mus_property ("pop-first")) + && !to_boolean (get_music ()->get_mus_property ("once")) + ) Translator_def::apply_pushpop_property (report_to (), sym, eprop, SCM_UNDEFINED); - Translator_def::apply_pushpop_property (report_to (), sym, eprop, val); + translator_def::apply_pushpop_property (report_to (), sym, eprop, val); + } + simple_music_iterator::process (m); +} + +make_scheme_callback(push_property_iterator,once_finalization, 2); +scm +push_property_iterator::once_finalization (scm trans, scm music) +{ + music * mus = unsmob_music (music); + translator_group *tg + = dynamic_cast (unsmob_translator (trans)); + + scm sym = mus->get_mus_property ("symbol"); + if (check_grob (mus, sym)) + { + scm eprop = mus->get_mus_property ("grob-property"); + + translator_def::apply_pushpop_property (tg, sym, eprop, scm_undefined); + } + return scm_unspecified; +} + +void +Push_property_iterator::do_quit () +{ + if (to_boolean (get_music ()->get_mus_property ("once"))) + { + SCM trans = report_to()->self_scm(); + SCM music = get_music ()->self_scm(); + + Global_translator * tg= report_to()->top_translator (); + tg->add_finalization (scm_list_n (once_finalization_proc, + trans, music, SCM_UNDEFINED)); } - Simple_music_iterator::process (m); } void @@ -97,7 +160,9 @@ Pop_property_iterator::process (Moment m) } + IMPLEMENT_CTOR_CALLBACK (Pop_property_iterator); IMPLEMENT_CTOR_CALLBACK (Push_property_iterator); IMPLEMENT_CTOR_CALLBACK (Property_iterator); IMPLEMENT_CTOR_CALLBACK (Property_unset_iterator); + diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 693158620b..ce13f5ec44 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -55,11 +55,8 @@ Score_engraver::make_columns () Grob_info i2 (musical_column_); i2.origin_trans_ = this; - announce_grob (i1); announce_grob (i2); - - } } @@ -145,6 +142,8 @@ Score_engraver::one_time_step () } stop_translation_timestep (); + + apply_finalizations (); check_removal (); @@ -176,7 +175,6 @@ Score_engraver::typeset_grob (Grob *elem) if (!elem) programming_error ("Score_engraver: empty elt\n"); else - elems_.push (elem); } diff --git a/lily/sequential-iterator.cc b/lily/sequential-iterator.cc index edd5ab5ee8..7c6f6c4a46 100644 --- a/lily/sequential-iterator.cc +++ b/lily/sequential-iterator.cc @@ -52,7 +52,8 @@ Sequential_iterator::get_music_list () const void Sequential_iterator::do_quit () { - if (iter_) iter_->quit(); + if (iter_) + iter_->quit(); } -- 2.39.5