+ Stream_event *nr = info.event_cause ();
+
+ /*
+ ugh. why not simply check for pitch?
+ */
+ if (!nr->in_event_class ("note-event"))
+ {
+ nr->origin ()->warning
+ (_ ("cannot determine pitch of ligature primitive -> skipping"));
+ at_beginning = true;
+ continue;
+ }
+
+ int pitch = unsmob_pitch (nr->get_property ("pitch"))->steps ();
+ int delta_pitch = 0;
+
+ if (at_beginning)
+ {
+ if (i == s - 1)
+ {
+ // we can get here after invalid input
+ nr->origin ()->warning
+ (_ ("single note ligature - skipping"));
+ break;
+ }
+ prev_semibrevis = prev_brevis_shape = false;
+ prev_primitive = NULL;
+ }
+ else
+ {
+ delta_pitch = pitch - prev_pitch;
+ if (delta_pitch == 0)
+ {
+ nr->origin ()->warning
+ (_ ("prime interval within ligature -> skipping"));
+ at_beginning = true;
+ primitive->set_property ("primitive",
+ scm_from_int (MLP_NONE));
+ continue;
+ }
+ }
+
+ if (duration_log < -3 // is this possible at all???
+ || duration_log > 0)
+ {
+ nr->origin ()->warning
+ (_ ("mensural ligature: duration none of Mx, L, B, S -> skipping"));
+ primitive->set_property ("primitive",
+ scm_from_int (MLP_NONE));
+ at_beginning = true;
+ continue;
+ }
+
+ // apply_transition replacement begins
+ bool general_case = true;
+
+ // first check special cases
+ // 1. beginning
+ if (at_beginning)
+ {
+ // a. semibreves
+ if (duration_log == 0)
+ {
+ primitive->set_property ("primitive",
+ scm_from_int (MLP_UP | MLP_BREVIS));
+ prev_semibrevis = prev_brevis_shape = true;
+ general_case = false;
+ }
+ // b. descendens longa or brevis
+ else if (i < s - 1
+ && (unsmob_pitch (primitives[i + 1].event_cause ()
+ ->get_property ("pitch"))->steps () < pitch)
+ && duration_log > -3)
+ {
+ int left_stem = duration_log == -1 ? MLP_DOWN : 0;
+
+ primitive->set_property ("primitive",
+ scm_from_int (left_stem | MLP_BREVIS));
+ prev_brevis_shape = true;
+ prev_semibrevis = general_case = false;
+ }
+ }
+ // 2. initial semibrevis must be followed by another one
+ else if (prev_semibrevis)
+ {
+ prev_semibrevis = false;
+ if (duration_log == 0)
+ {
+ primitive->set_property ("primitive", scm_from_int (MLP_BREVIS));
+ general_case = false;
+ }
+ else
+ {
+ nr->origin ()->warning
+ (_ ("semibrevis must be followed by another one -> skipping"));
+ primitive->set_property ("primitive",
+ scm_from_int (MLP_NONE));
+ at_beginning = true;
+ continue;
+ }
+ }
+ // 3. semibreves are otherwise not allowed
+ else if (duration_log == 0)
+ {
+ nr->origin ()->warning
+ (_ ("semibreves can only appear at the beginning of a ligature,\n"
+ "and there may be only zero or two of them"));
+ primitive->set_property ("primitive",
+ scm_from_int (MLP_NONE));
+ at_beginning = true;
+ continue;
+ }
+ // 4. end, descendens
+ else if (i == s - 1 && delta_pitch < 0)
+ {
+ // brevis; previous note must be turned into flexa
+ if (duration_log == -1)
+ {
+ if (prev_brevis_shape)
+ {
+ prev_primitive->set_property
+ ("primitive",
+ scm_from_int
+ (MLP_FLEXA
+ | (scm_to_int (prev_primitive->get_property ("primitive"))
+ & MLP_DOWN)));
+ primitive->set_property ("primitive", scm_from_int (MLP_NONE));
+ break; // no more notes, no join
+ }
+ else
+ {
+ nr->origin ()->warning
+ (_ ("invalid ligatura ending:\n"
+ "when the last note is a descending brevis,\n"
+ "the penultimate note must be another one,\n"
+ "or the ligatura must be LB or SSB"));
+ primitive->set_property ("primitive", scm_from_int (MLP_NONE));
+ break;
+ }
+ }
+ // longa
+ else if (duration_log == -2)
+ {
+ primitive->set_property ("primitive", scm_from_int (MLP_BREVIS));
+ general_case = false;
+ }
+ // else maxima; fall through regular case below
+ }
+
+ if (general_case)
+ {
+ static int const shape[3] = {MLP_MAXIMA, MLP_LONGA, MLP_BREVIS};
+
+ primitive->set_property ("primitive",
+ scm_from_int (shape[duration_log + 3]));
+ prev_brevis_shape = duration_log == -1;
+ }
+
+ // join_primitives replacement
+ if (!at_beginning)
+ {
+ /*
+ if the previous note is longa-shaped and this note is lower,
+ then the joining line may hide the stem, so it is made longer
+ to serve as stem as well
+ */
+ if (delta_pitch < 0
+ && (scm_to_int (prev_primitive->get_property ("primitive"))
+ & MLP_LONGA))
+ {
+ delta_pitch -= 6;
+ // instead of number 6
+ // the legth of the longa stem should be queried something like
+ // Font_interface::get_default_font (ligature)->find_by_name
+ // ("noteheads.sM2mensural").extent (Y_AXIS).length ()
+ }
+ prev_primitive->set_property ("join-right-amount",
+ scm_from_int (delta_pitch));
+ // perhaps set add-join as well
+ }
+ at_beginning = false;
+ prev_primitive = primitive;
+ prev_pitch = pitch;
+ // apply_transition replacement ends