+
+ last_stem_added_at_ = now;
+
+ Duration *stem_duration = unsmob_duration (ev->get_property ("duration"));
+ int durlog = stem_duration->duration_log ();
+ //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.
+ */
+ }
+
+ if (forced_direction_)
+ set_grob_direction (stem, forced_direction_);
+
+ 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),
+ Stem::is_invisible (stem),
+ stem_duration->factor (),
+ (stem->get_property ("tuplet-start") == SCM_BOOL_T));
+ Beam::add_stem (beam_, stem);
+}
+
+ADD_ACKNOWLEDGER (Beam_engraver, stem);
+ADD_ACKNOWLEDGER (Beam_engraver, rest);
+
+ADD_TRANSLATOR (Beam_engraver,
+ /* doc */
+ "Handle @code{Beam} events by engraving beams. If omitted,"
+ " then notes are printed with flags instead of beams.",
+
+ /* create */
+ "Beam ",
+
+ /* read */
+ "baseMoment "
+ "beamMelismaBusy "
+ "beatStructure "
+ "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);