+void
+Beam_engraver::acknowledge_stem (Grob_info info)
+{
+ if (!beam_)
+ return;
+
+ Moment now = now_mom ();
+ if (!valid_start_point ())
+ return;
+
+ Item *stem = dynamic_cast<Item *> (info.grob ());
+ if (Stem::get_beam (stem))
+ return;
+
+
+
+ Stream_event *ev = info.ultimate_event_cause ();
+ if (!ev->in_event_class ("rhythmic-event"))
+ {
+ info.grob ()->warning (_ ("stem must have Rhythmic structure"));
+ return;
+ }
+
+ last_stem_added_at_ = now;
+ int durlog = unsmob_duration (ev->get_property ("duration"))->duration_log ();
+ if (durlog <= 2)
+ {
+ ev->origin ()->warning (_ ("stem does not fit in beam"));
+ prev_start_ev_->origin ()->warning (_ ("beam was started here"));
+ /*
+ don't return, since
+
+ [r4 c8] can just as well be modern notation.
+ */
+ }
+
+ stem->set_property ("duration-log",
+ scm_from_int (durlog));
+ Moment stem_location = now - beam_start_mom_ + beam_start_location_;
+ beam_info_->add_stem (stem_location,
+ max (durlog- 2, 0));
+ Beam::add_stem (beam_, stem);
+}
+
+ADD_ACKNOWLEDGER (Beam_engraver, stem);
+ADD_ACKNOWLEDGER (Beam_engraver, rest);
+
+ADD_TRANSLATOR (Beam_engraver,
+ /* doc */
+
+ "Handles Beam events by engraving Beams. If omitted, then notes will be "
+ "printed with flags instead of beams.",
+
+ /* create */ "Beam",
+
+ /* read */
+ "beamMelismaBusy "
+ "beatLength "
+ "subdivideBeams "
+ ,
+ /* write */
+ "forbidBreak");
+
+class Grace_beam_engraver : public Beam_engraver
+{
+public:
+ TRANSLATOR_DECLARATIONS (Grace_beam_engraver);
+
+ DECLARE_TRANSLATOR_LISTENER (beam);
+
+protected:
+ virtual bool valid_start_point ();
+ virtual bool valid_end_point ();
+};
+
+Grace_beam_engraver::Grace_beam_engraver ()
+{
+}
+
+bool
+Grace_beam_engraver::valid_start_point ()
+{
+ Moment n = now_mom ();
+
+ return n.grace_part_ != Rational (0);
+}
+
+bool
+Grace_beam_engraver::valid_end_point ()
+{
+ return beam_ && valid_start_point ();
+}
+
+/*
+ Ugh, C&P code.
+ */
+IMPLEMENT_TRANSLATOR_LISTENER (Grace_beam_engraver, beam);
+void
+Grace_beam_engraver::listen_beam (Stream_event *ev)
+{
+ Direction d = to_dir (ev->get_property ("span-direction"));
+
+ if (d == START && valid_start_point ())
+ start_ev_ = ev;
+ else if (d == STOP && valid_end_point ())
+ stop_ev_ = ev;
+}
+
+
+ADD_ACKNOWLEDGER (Grace_beam_engraver, stem);
+ADD_ACKNOWLEDGER (Grace_beam_engraver, rest);
+
+ADD_TRANSLATOR (Grace_beam_engraver,
+
+ /* doc */
+
+ "Handles Beam events by engraving Beams. If omitted, then notes will "
+ "be printed with flags instead of beams. Only engraves beams when we "
+ " are at grace points in time. ",
+
+ /* create */ "Beam",
+ /* read */
+ "beamMelismaBusy "
+ "beatLength "
+ "subdivideBeams "
+ ,
+ /* write */ "");