+/*
+Should make this optional? It will also complain when you do
+
+ [s4]
+
+which is entirely legitimate.
+
+Or we can scrap it. Barchecks should detect wrong durations, and
+skipTypesetting speeds it up a lot.
+*/
+
+void
+My_lily_parser::beam_check (SCM dur)
+{
+ Duration *d = unsmob_duration (dur);
+ if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
+ {
+ Music * m = unsmob_music (last_beam_start_);
+ m->origin ()->warning (_("Suspect duration found following this beam"));
+ }
+ last_beam_start_ = SCM_EOL;
+}
+
+
+
+
+/*
+
+It is a little strange to have this function in this file, but
+otherwise, we have to import music classes into the lexer.
+
+*/
+int
+My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid)
+{
+ if (gh_string_p (sid)) {
+ *destination = sid;
+ return STRING_IDENTIFIER;
+ } else if (gh_number_p (sid)) {
+ *destination = sid;
+ return NUMBER_IDENTIFIER;
+ } else if (unsmob_context_def (sid)) {
+ *destination = unsmob_context_def (sid)->clone_scm();
+ return TRANSLATOR_IDENTIFIER;
+ } else if (unsmob_score (sid)) {
+ Score *sc = new Score (*unsmob_score (sid));
+ *destination =sc->self_scm ();
+ return SCORE_IDENTIFIER;
+ } else if (Music * mus =unsmob_music (sid)) {
+ *destination = unsmob_music (sid)->clone ()->self_scm();
+ unsmob_music (*destination)->
+ set_mus_property ("origin", make_input (last_input_));
+ return dynamic_cast<Event*> (mus)
+ ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
+ } else if (unsmob_duration (sid)) {
+ *destination = unsmob_duration (sid)->smobbed_copy();
+ return DURATION_IDENTIFIER;
+ } else if (unsmob_music_output_def (sid)) {
+ Music_output_def *p = unsmob_music_output_def (sid);
+ p = p->clone ();
+
+ *destination = p->self_scm();
+ return MUSIC_OUTPUT_DEF_IDENTIFIER;
+ } else if (Text_item::markup_p (sid)) {
+ *destination = sid;
+ return MARKUP_IDENTIFIER;
+ }
+
+ return -1;
+}
+
+Music *
+property_op_to_music (SCM op)
+{
+ Music * m = 0;
+ SCM tag = gh_car (op);
+ SCM symbol = gh_cadr (op);
+ SCM args = gh_cddr (op);
+ SCM grob_val = SCM_UNDEFINED;
+ SCM grob_sym = SCM_UNDEFINED;
+ SCM val = SCM_UNDEFINED;
+
+ if (tag == ly_symbol2scm ("assign"))
+ {
+ m = MY_MAKE_MUSIC("PropertySet");
+ val = gh_car (args);
+ }
+ else if (tag == ly_symbol2scm ("unset"))
+ m = MY_MAKE_MUSIC("PropertyUnset");
+ else if (tag == ly_symbol2scm ("poppush")
+ || tag == ly_symbol2scm ("push"))
+ {
+ m = MY_MAKE_MUSIC("OverrideProperty");
+ grob_sym = gh_car (args);
+ grob_val = gh_cadr (args);
+ }
+ else if (tag == ly_symbol2scm ("pop")) {
+ m = MY_MAKE_MUSIC("RevertProperty");
+ grob_sym = gh_car (args);
+ }
+
+ m->set_mus_property ("symbol", symbol);
+
+ if (val != SCM_UNDEFINED)
+ m->set_mus_property ("value", val);
+ if (grob_val != SCM_UNDEFINED)
+ m->set_mus_property ("grob-value", grob_val);
+
+ if (grob_sym != SCM_UNDEFINED)
+ {
+ bool itc = internal_type_checking_global_b;
+ /* UGH.
+ */
+ bool autobeam = gh_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
+ if (autobeam)
+ internal_type_checking_global_b = false;
+ m->set_mus_property ("grob-property", grob_sym);
+ if (autobeam)
+ internal_type_checking_global_b = itc;
+ }
+
+ if (op == ly_symbol2scm ("poppush"))
+ m->set_mus_property ("pop-first", SCM_BOOL_T);
+
+
+ return m;
+}
+
+Music*
+context_spec_music (SCM type, SCM id, Music * m, SCM ops)
+{
+ Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
+
+ csm->set_mus_property ("element", m->self_scm ());
+ scm_gc_unprotect_object (m->self_scm ());
+
+ csm->set_mus_property ("context-type",
+ gh_symbol_p (type) ? type : scm_string_to_symbol (type));
+ csm->set_mus_property ("property-operations", ops);
+
+ if (gh_string_p (id))
+ csm->set_mus_property ("context-id", id);
+ return csm;
+}
+
+
+SCM
+get_next_unique_context ()
+{
+ static int new_context_count;
+
+ char s[1024];
+ snprintf (s, 1024, "uniqueContext%d", new_context_count ++);
+
+ return scm_makfrom0str (s);
+}
+