+2003-12-31 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * lily/melisma-engraver.cc (try_music): use melisma_busy()
+
+ * lily/lyric-engraver.cc (process_music): remove alignment kludge
+
+ * lily/lyric-combine-music-iterator.cc (melisma_busy): new function.
+
+ * lily/stanza-number-engraver.cc (acknowledge_grob): rewrite
+
+ * scm/define-grobs.scm (all-grob-descriptions): change
+ StanzaNumber description: make side support, i.s.o. breakable.
+ use Instrument_name_engraver for texts in the margin.
+
+ * scm/define-translator-properties.scm: remove
+ melismaEngraverBusy, stz property.
+
+ * *.cc: naming: change empty_b () into is_empty ()
+
+ * lily/self-aligment-interface.cc (aligned_on_parent): new function.
+
+ * input/regression/lyric-phrasing-new.ly: new file.
+
+ * lily/new-phrasing-engraver.cc (process_acknowledged_grobs): new
+ engraver, redo lyric phrasing, but cleaner and simpler. Lyrics on
+ melismata are now left-aligned.
+
2003-12-30 Han-Wen Nienhuys <hanwen@cs.uu.nl>
* input/mutopia/F.Schubert/GNUmakefile: add morgenlied.ly
}
@end lilypond
-Stanza numbers, or the names of the singers can be added by setting
-@code{LyricsVoice.Stanza} (for the first system) and
-@code{LyricsVoice.stz} for the following systems. Notice how dots are
-surrounded with spaces in @code{\lyrics} mode:
+@cindex stanza number
+@cindex singer's names
+@cindex name of singer
+
+Stanza numbers can be added by setting @code{LyricsVoice.stanza}, e.g.
@example
\property LyricsVoice . stanza = "Bert"
\property LyricsVoice . stanza = "Ernie"
@end example
+Notice how dots are surrounded with spaces in @code{\lyrics} mode, to
+prevent @code{LyricsVoice.stanza} being interpreted as a single
+string.
+
+Names of the singers should be added using @code{LyricsVoice
+. instrument} and @code{LyricsVoice . instr}, analogous to instrument
+annotations for staves.
+
To make empty spaces in lyrics, use @code{\skip}.
MAJOR_VERSION=2
MINOR_VERSION=1
PATCH_LEVEL=4
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=hwn1
Path::to_string () const
{
String s;
- if (!root.empty_b ())
+ if (!root.is_empty ())
s = root + ::to_string (ROOTSEP);
- if (!dir.empty_b ())
+ if (!dir.is_empty ())
s += dir + ::to_string (DIRSEP);
s += base;
- if (!ext.empty_b ())
+ if (!ext.is_empty ())
s += ::to_string (EXTSEP) + ext;
return s;
}
static T infinity () ;
static String T_to_string (T arg);
T center () const {
- assert (!empty_b ());
+ assert (!is_empty ());
return (elem (LEFT) + elem (RIGHT)) / T (2);
}
void translate (T t)
/*
TODO: strip hungarian suffix.
*/
- bool empty_b () const { return elem (LEFT) > elem (RIGHT); }
+ bool is_empty () const { return elem (LEFT) > elem (RIGHT); }
bool contains_b (Interval_t<T> const&) const;
Interval_t () {
set_empty ();
return *this;
}
Interval_t<T> &operator *= (T r) {
- if (!empty_b ())
+ if (!is_empty ())
{
elem (LEFT) *= r;
elem (RIGHT) *= r;
String
Interval_t<T>::to_string () const
{
- if (empty_b ())
+ if (is_empty ())
return "[empty]";
String s ("[");
void operator += (char const* s) { strh_ += s; }
void operator += (String s);
- bool empty_b () const;
+ bool is_empty () const;
void append (String);
void prepend (String);
}
bool
-String::empty_b () const
+String::is_empty () const
{
return !length ();
}
not be in the PD - but I am assuming there are no notable ones in
this small piece.
- The original compresses the entire music onto a single page, in 4
-systems. "
+ The original compresses the entire music onto a single page, in 4 systems."
}
melody = \notes \relative c'' \repeat volta 2 \context Voice = singer {
\time 6/8
\autoBeamOff
- \property Voice.automaticMelismata = ##t
s1*0^\markup { \bold \bigger\bigger { \hspace #-3.0 Lieblich, etwas geschwind } }
R2.
r4 r8 c4 g8 |
firstVerse = \lyrics {
+ \property LyricsVoice . stanza = "1."
+
Sü -- ßes Licht! Aus gol -- de -- nen Pfor -- ten brichst du __ \break
sie -- gend durch __ die Nacht. Schö -- ner Tag, du __ bist er -- wacht. __ Mit \break
ge -- heim -- nis -- vol -- len Wor -- ten, in me -- lo -- di -- schen Ak -- kor -- den, grüß __ ich __ \break
}
secondVerse = \lyrics {
+ \property LyricsVoice . stanza = "2."
+
Ach, der Lie -- be sanf "" -- tes We -- hen schwellt mir
das be -- weg -- te __ Herz, sanft, wie ein ge -- lieb -- ter Schmerz. __ Dürft ich
nur auf gold -- nen Hö -- hen mich im Mor -- gen -- duft er -- ge -- hen! Sehn -- sucht
\context LyricsVoice = "singer-2" \secondVerse
>>
\new PianoStaff <<
- \property PianoStaff.instrument = #"2 "
+ \property PianoStaff.instrument = \markup { \bold \bigger "2. " }
\new Staff \pianoRH
\new Staff \pianoLH
>>
\translator { \PianoStaffContext
VerticalAlignment \override #'forced-distance = #10
}
+ \translator {
+ \ScoreContext
+ \remove "Lyric_phrasing_engraver"
+ \consists "New_phrasing_engraver"
+ }
}
}
--- /dev/null
+\header {
+
+texidoc = "Lyric phrasing:
+
+ Normally, the lyric is centered on the note head. However, on
+ melismata, the text is left aligned on the left-side of the note head.
+
+"
+}
+
+
+\score{
+\context Staff {
+ \addlyrics
+ \notes \relative c' \context Voice = "bla" {
+ \autoBeamOff
+ c4( c16 d c b) c4
+ d16[ e f g]
+
+ }
+ \lyrics \context LyricsVoice = "bla-1" {
+ al tijd
+ izzz
+ }
+
+ }
+
+\paper { raggedright = ##t
+
+ \translator {
+ \ScoreContext
+ \remove "Lyric_phrasing_engraver"
+ \consists "New_phrasing_engraver"
+ }
+ \translator {
+ \VoiceContext
+
+ }
+ }
+}
+
-\version "1.9.8"
+\version "2.1.4"
+
\header {
-texidoc = "Stanza numbers may differ for the first and following systems."
+texidoc = "Stanza numbers are put left of their lyric."
}
\score {
<<
+ \notes { r4 r4 c4 c4 }
\context LyricsVoice
\lyrics {
- \property LyricsVoice . stanza = "first"
- \property LyricsVoice . stz = \markup { "32" \super "nd" }
- Foo1 Bar1
+ \skip 2
+ \property LyricsVoice . stanza = "1."
+ Foo8 Bar8
}
- \notes { c''1 \break c''1 }
>>
\paper { raggedright = ##t }
*/
static int
-number_accidentals (SCM sig, Music * note, Pitch *pitch, SCM curbarnum, SCM lazyness,
+number_accidentals (SCM sig, Music *, Pitch *pitch, SCM curbarnum, SCM lazyness,
bool ignore_octave_b)
{
int n = pitch->get_notename ();
else if (gh_symbol_p (ly_car (accidentals)))
{
SCM context =ly_car (accidentals);
- while (origin && !origin->is_alias_b (context))
+ while (origin && !origin->is_alias (context))
origin = origin->daddy_trans_;
if (!origin)
extent.unite (which->elem(i)->extent (item_col, X_AXIS));
}
- if (!extent.empty_b())
+ if (!extent.is_empty ())
{
Real p = gh_scm2double (me->get_grob_property ("left-padding"));
extent[LEFT] -= p;
String font_char = get_fontcharname (style, alteration);
Molecule acc (fm->find_by_name ("accidentals-" + font_char));
- if (acc.empty_b())
+ if (acc.is_empty ())
{
me->warning (_f ("accidental `%s' not found", font_char));
}
for (int i=0; i < all_grobs.size (); i++)
{
Interval y = all_grobs[i]->extent (me, a);
- if (!y.empty_b ())
+ if (!y.is_empty ())
{
Grob *e =dynamic_cast<Grob*> (all_grobs[i]);
{
String path;
- if (path.empty_b ())
+ if (path.is_empty ())
path = search_path_.find (name + ".afm");
- if (path.empty_b ())
+ if (path.is_empty ())
{
String p = kpathsea_find_afm (name.to_str0 ());
if (p.length ())
path = p;
}
- if (path.empty_b ())
+ if (path.is_empty ())
return 0;
if (verbose_global_b)
{
String path;
- if (path.empty_b ())
+ if (path.is_empty ())
{
String p = kpathsea_find_tfm (name.to_str0 ());
if (p.length ())
path = p;
}
- if (path.empty_b ())
+ if (path.is_empty ())
path = search_path_.find (name + ".tfm");
- if (path.empty_b ())
+ if (path.is_empty ())
return 0;
if (verbose_global_b)
{
note_head_style = String ("noteheads-2");
}
- if (Font_interface::get_default_font (me)->find_by_name (note_head_style).empty_b ())
+ if (Font_interface::get_default_font (me)->find_by_name (note_head_style).is_empty ())
{
String message = "Ambitus: no such note head: `" + note_head_style + "'";
me->warning (_ (message.to_str0 ()));
- my_y);
}
- if (heads.empty_b ())
+ if (heads.is_empty ())
{
/*
Dumb blonde error
If \translator Staff = bass, then look for Staff = *
*/
- while (current && !current->is_alias_b (to_type_sym))
+ while (current && !current->is_alias (to_type_sym))
{
last = current;
current = current->daddy_trans_;
{
Grob * se = unsmob_grob (ly_car (s));
Interval dims = se->extent (common, a);
- if (!dims.empty_b ())
+ if (!dims.is_empty ())
r.unite (dims);
}
return r;
return false;
if (d == START)
- evs_drul_[d] = m;
+ {
+ evs_drul_[d] = m;
+ }
else if (d==STOP)
{
now_stop_ev_ = m;
}
void
-Beam_engraver::set_melisma (bool m)
+Beam_engraver::set_melisma (bool ml)
{
- daddy_trans_->set_property ("beamMelismaBusy", m ? SCM_BOOL_T :SCM_BOOL_F);
+ SCM m = get_property ("automaticMelismata");
+ SCM b = get_property ("autoBeaming");
+
+ if (to_boolean (m) && !to_boolean (b))
+ daddy_trans_->set_property ("beamMelismaBusy", ml ? SCM_BOOL_T :SCM_BOOL_F);
}
void
return;
}
+ set_melisma (true);
prev_start_ev_ = evs_drul_[START];
beam_ = new Spanner (get_property ("Beam"));
SCM smp = get_property ("measurePosition");
if (beam_)
{
- SCM m = get_property ("automaticMelismata");
- SCM b = get_property ("autoBeaming");
- if (to_boolean (m) && !to_boolean (b))
- {
- set_melisma (true);
- }
+ set_melisma (true);
+
subdivide_beams_ = to_boolean(get_property("subdivideBeams"));
beat_length_ = *unsmob_moment (get_property ("beatLength"));
}
beam_ = 0;
beam_info_ = 0;
typeset_beam();
-
- if (to_boolean (get_property ("automaticMelismata"))
- && !to_boolean (get_property ("autoBeaming")))
- {
set_melisma (false);
- }
}
}
}
while (flip (&d) != LEFT);
- if (!new_slice.empty_b())
+ if (!new_slice.is_empty ())
last_int = new_slice;
}
else
s.intersect (allowed_regions_[i]);
- if (!s.empty_b ())
+ if (!s.is_empty ())
{
Interval before = allowed_regions_[i];
Interval after = allowed_regions_[i];
before[RIGHT] = s[LEFT];
after[LEFT] = s[RIGHT];
- if (!before.empty_b() && before.length () > 0.0)
+ if (!before.is_empty () && before.length () > 0.0)
{
allowed_regions_.insert (before, i);
i++;
}
allowed_regions_.del (i);
- if (!after.empty_b () && after.length () > 0.0)
+ if (!after.is_empty () && after.length () > 0.0)
{
allowed_regions_.insert (after, i);
i++;
continue;
Interval hps = Stem::head_positions (stem);
- if(!hps.empty_b())
+ if(!hps.is_empty ())
{
hps[LEFT] += -1;
hps[RIGHT] += 1;
stem->set_grob_property ("direction", scm_int2num (d));
hps.intersect (max_gap);
- assert (hps.empty_b () || hps.length () < 1e-6 );
+ assert (hps.is_empty () || hps.length () < 1e-6 );
}
}
}
feasible_left_point.intersect (flp);
}
- if (feasible_left_point.empty_b())
+ if (feasible_left_point.is_empty ())
{
warning (_("Not sure that we can find a nice beam slope (no viable initial configuration found)."));
}
if (french)
{
Slice bm = where_are_the_whole_beams (beaming);
- if (!bm.empty_b())
+ if (!bm.is_empty ())
stem_y += beam_translation * bm[-my_dir];
}
else
{
Slice bm = Stem::beam_multiplicity(s);
- if (!bm.empty_b())
+ if (!bm.is_empty ())
stem_y +=bm[my_dir] * beam_translation;
}
/*
sort out how interfacing this should work;
*/
- if (line.empty_b ())
+ if (line.is_empty ())
{
sp->line_len_ = -1;
}
{
Interval y = elems[i]->extent (elems[i], X_AXIS);
extents.push (y);
- if (!y.empty_b())
+ if (!y.is_empty ())
last_nonempty = i;
}
int idx = 0;
- while (idx < extents.size () && extents[idx].empty_b ())
+ while (idx < extents.size () && extents[idx].is_empty ())
idx++;
Array<Real> offsets;
{
int next_idx = idx+1;
while (next_idx < elems.size() &&
- extents[next_idx].empty_b()
+ extents[next_idx].is_empty ()
)
next_idx++;
/*
duh, don't support scores with more than 32000 systems.
*/
- if (sr.empty_b())
+ if (sr.is_empty ())
{
/*
overflow if we don't treat this specially.
If \translator Staff = bass, then look for Staff = *
*/
- while (current && !current->is_alias_b (to_type))
+ while (current && !current->is_alias (to_type))
{
last = current;
current = current->daddy_trans_;
String glyph = String (ly_scm2string (glyph_scm));
Font_metric *fm = Font_interface::get_default_font (me);
Molecule out = fm->find_by_name (glyph);
- if (out.empty_b())
+ if (out.is_empty ())
{
me->warning (_f ("clef `%s' not found", glyph.to_str0 ()));
}
Molecule molecule
= Font_interface::get_default_font (me)->find_by_name (font_char);
- if (molecule.empty_b ())
+ if (molecule.is_empty ())
{
me->warning (_f ("custos `%s' not found", font_char));
return SCM_EOL;
break;
}
}
- if (ydims.empty_b ())
+ if (ydims.is_empty ())
ydims = Interval (0,0);
return Box (Interval (0, w), ydims);
{
if (prefix_set & mask)
{
- if (!str->empty_b ())
+ if (!str->is_empty ())
*str += ", ";
*str += name;
}
make the padding a little smaller, here.
*/
Interval e =b->extent (common, X_AXIS);
- if (e.empty_b ())
+ if (e.is_empty ())
e = Interval (0,0) + b->relative_coordinate (common, X_AXIS);
x_points[d] = e.center () - d * padding /3; // ugh.
else
{
Interval e =b->extent (common, X_AXIS);
- if (!e.empty_b ())
+ if (!e.is_empty ())
x_points[d] = e[-d] - d*padding;
}
}
{
Interval iv = sp->get_bound (d)->extent (common, X_AXIS);
- bounds[d] = iv.empty_b ()
+ bounds[d] = iv.is_empty ()
? sp->get_bound (d)->relative_coordinate (common, X_AXIS)
: iv[-d];
}
we should probably do something more intelligent when bounds is
empty, but at least this doesn't crash.
*/
- Real w = bounds.empty_b () ? 0 : bounds.length ();
+ Real w = bounds.is_empty () ? 0 : bounds.length ();
/* for length, use a geometric mean of the available space and some minimum
*/
}
Box b (Interval (-l/2,l/2), Interval (h,h+th));
Molecule mol (Lookup::filledbox (b));
- Real ct = bounds.empty_b () ? 0 : bounds.center () ;
+ Real ct = bounds.is_empty () ? 0 : bounds.center () ;
mol.translate_axis (ct -sp->relative_coordinate (common, X_AXIS), X_AXIS);
return mol.smobbed_copy ();
}
codify THIS into a Scheme expression.
*/
SCM create_scheme () const;
- bool empty_b () const;
+ bool is_empty () const;
static SCM ly_get_molecule_extent (SCM mol, SCM axis);
static bool has_interface (Grob*);
DECLARE_SCHEME_CALLBACK (aligned_on_self, (SCM element, SCM axis));
DECLARE_SCHEME_CALLBACK (centered_on_parent, (SCM element, SCM axis));
+ DECLARE_SCHEME_CALLBACK (aligned_on_parent, (SCM element, SCM axis));
DECLARE_SCHEME_CALLBACK (centered_on_other_axis_parent, (SCM element, SCM axis));
};
#endif
Translator_group* get_ancestor (int l=1);
int get_depth () const;
bool is_bottom_translator_b () const;
- bool removable_b () const;
+ bool is_removable () const;
void terminate_translator (Translator*r);
Translator *remove_translator (Translator*trans);
void check_removal ();
virtual void each (Method_pointer);
};
+
+bool melisma_busy (Translator* tr); // where to put this? --hwn
+
+
#endif // TRANSLATOR_GROUP_HH
public:
Music_output_def * output_def_;
- bool is_alias_b (SCM) const;
+ bool is_alias (SCM) const;
Translator (Translator const &);
out = " ";
}
String dep = deps[i];
- if (!dependency_prefix_global.empty_b ())
+ if (!dependency_prefix_global.is_empty ())
{
if (dep.index ('/') < 0)
dep = dependency_prefix_global + dep;
void
do_one_file (String init, String in_file, String out_file)
{
- if (init.length () && global_path.find (init).empty_b ())
+ if (init.length () && global_path.find (init).is_empty ())
{
warning (_f ("can't find file: `%s'", init));
warning (_f ("(search path: `%s')", global_path.to_string ().to_str0 ()));
return;
}
- if ((in_file != "-") && global_path.find (in_file).empty_b ())
+ if ((in_file != "-") && global_path.find (in_file).is_empty ())
{
warning (_f ("can't find file: `%s'", in_file));
return;
Accidental_interface::get_fontcharname (style, alteration);
Molecule acc (fm->find_by_name ("accidentals-" + font_char));
- if (acc.empty_b())
+ if (acc.is_empty ())
{
me->warning (_f ("accidental `%s' not found", font_char));
}
};
+bool
+melisma_busy (Translator* tr)
+{
+ SCM melisma_properties = tr->get_property ("melismaBusyProperties");
+ bool busy = false;
+
+ for (; gh_pair_p (melisma_properties);
+ melisma_properties = gh_cdr (melisma_properties))
+ busy = busy || to_boolean (tr->internal_get_property (gh_car (melisma_properties)));
+
+ return busy;
+}
+
+
/*
Ugh, why static?
text_= new Item (get_property ("LyricText"));
text_->set_grob_property ("text", req_->get_mus_property ("text"));
-
- /*
- We can't reach the notehead where we're centered from here. So
- we kludge.
-
- (UGH UGH, pulled amount of space out of thin air)
- */
-
- text_->translate_axis (0.66, X_AXIS);
-
announce_grob (text_, req_->self_scm());
}
}
record_notehead (voice_context_id, h);
/* is it in a melisma ? */
- if (to_boolean (i.origin_trans_->get_property ("melismaEngraverBusy")))
+ if (melisma_busy (i.origin_trans_))
{
record_melisma (voice_context_id);
}
String
get_context_id (Translator_group * ancestor, SCM type)
{
- while (ancestor != 0 && !ancestor->is_alias_b(type))
+ while (ancestor && !ancestor->is_alias(type))
{
ancestor = ancestor->daddy_trans_;
}
- if (ancestor != 0)
+ if (ancestor)
{
return ancestor->id_string_;
}
/* creats*/ "",
/* accepts */ "",
/* acks */ "lyric-syllable-interface note-head-interface lyric-extender-interface",
- /* reads */ "automaticPhrasing melismaEngraverBusy associatedVoice phrasingPunctuation",
+ /* reads */ "automaticPhrasing associatedVoice phrasingPunctuation",
/* write */ "");
distill_inname (String str)
{
Path p = split_path (str);
- if (str.empty_b () || str == "-")
+ if (str.is_empty () || str == "-")
p.base = "-";
else
{
for (int i = 0; extensions[i]; i++)
{
p.ext = orig_ext;
- if (*extensions[i] && !p.ext.empty_b ())
+ if (*extensions[i] && !p.ext.is_empty ())
p.ext += ".";
p.ext += extensions[i];
- if (!global_path.find (p.to_string ()).empty_b ())
+ if (!global_path.find (p.to_string ()).is_empty ())
break;
}
/* Reshuffle extension */
outpath.root = "";
outpath.dir = "";
- if (!output_name_global.empty_b ())
+ if (!output_name_global.is_empty ())
outpath = split_path (output_name_global);
String init;
- if (!init_name_global.empty_b ())
+ if (!init_name_global.is_empty ())
init = init_name_global;
else
init = "init.ly";
{
String s = oparser_p_static->optional_argument_str0_;
Path p = split_path (s);
- if (s != "-" && p.ext.empty_b ())
+ if (s != "-" && p.ext.is_empty ())
p.ext = output_format_global;
output_name_global = p.to_string ();
Interval rext = me->get_bound (RIGHT)->extent (common, X_AXIS);
- Real w =(rext.empty_b()
+ Real w =(rext.is_empty ()
? me->get_bound (RIGHT)->relative_coordinate (common, X_AXIS)
: rext[RIGHT])
- me->get_bound (LEFT)->relative_coordinate (common, X_AXIS);
bool
-Melisma_engraver::try_music (Music *m)
+Melisma_engraver::try_music (Music *)
{
- SCM melisma_properties = get_property ("melismaBusyProperties");
- bool busy = false;
-
- for (; gh_pair_p (melisma_properties);
- melisma_properties = gh_cdr (melisma_properties))
-
- busy = busy || to_boolean (internal_get_property (gh_car (melisma_properties)));
-
/*
- for the phrasing engraver we also need this.
+ This can only be melisma-playing-event.
*/
- daddy_trans_->set_property ("melismaEngraverBusy",gh_bool2scm (busy));
- return busy;
+ return melisma_busy (this);
}
Melisma_engraver::Melisma_engraver()
}
ENTER_DESCRIPTION(Melisma_engraver,
-/* descr */ "",
+/* descr */ "This engraver collects melisma information about ties, beams, and user settings (@code{melismaBusy}, and signals it to the @code{\addlyrics} code. ",
/* creats*/ "",
/* accepts */ "melisma-playing-event",
/* acks */ "",
/* reads */ "melismaBusy melismaBusyProperties slurMelismaBusy tieMelismaBusy beamMelismaBusy",
-/* write */ "melismaEngraverBusy");
+/* write */ "");
expr_ = scm_list_n (ly_symbol2scm ("translate-molecule"),
ly_offset2scm (o),
expr_, SCM_UNDEFINED);
- if (!empty_b ())
+ if (!is_empty ())
dim_.translate (o);
}
void
Molecule::align_to (Axis a, Real x)
{
- if (empty_b())
+ if (is_empty ())
return ;
Interval i (extent (a));
Molecule::add_at_edge (Axis a, Direction d, Molecule const &m, Real padding,
Real minimum)
{
- Real my_extent= empty_b () ? 0.0 : dim_[a][d];
+ Real my_extent= is_empty () ? 0.0 : dim_[a][d];
Interval i (m.extent (a));
Real his_extent;
- if (i.empty_b ())
+ if (i.is_empty ())
{
programming_error ("Molecule::add_at_edge: adding empty molecule.");
his_extent = 0.0;
while expr_ == '()
*/
bool
-Molecule::empty_b () const
+Molecule::is_empty () const
{
return expr_ == SCM_EOL;
}
{
SCM context = ly_car (accidentals);
- while (origin && !origin->is_alias_b (context))
+ while (origin && !origin->is_alias (context))
origin = origin->daddy_trans_;
if (!origin)
void
New_fingering_engraver::add_script (Grob * head,
Music * event,
- Music * head_event)
+ Music * )
{
Finger_tuple ft ;
articulations_.push (ft);
announce_grob (g, event->self_scm ());
-
ft.script_->set_parent (head, X_AXIS);
}
--- /dev/null
+/*
+ new-phrasing-engraver.cc -- implement New_phrasing_engraver
+
+source file of the GNU LilyPond music typesetter
+
+(c) 2003--2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ */
+
+#include "translator-group.hh"
+#include "engraver.hh"
+#include "note-head.hh"
+#include "grob.hh"
+
+struct Phrasing_association
+{
+ String name_;
+ Link_array<Grob> lyrics_;
+ Link_array<Grob> heads_;
+ bool melisma_;
+ bool last_melisma_;
+
+ Phrasing_association()
+ {
+ melisma_ = false;
+ last_melisma_ = false;
+ }
+
+ void clear () {
+ lyrics_.clear ();
+ heads_.clear ();
+ }
+
+};
+
+class New_phrasing_engraver : public Engraver
+{
+public:
+ ~New_phrasing_engraver ();
+ TRANSLATOR_DECLARATIONS(New_phrasing_engraver);
+protected:
+ virtual void acknowledge_grob (Grob_info);
+ virtual void process_acknowledged_grobs ();
+ virtual void stop_translation_timestep ();
+
+ Link_array<Phrasing_association> assocs_;
+ void add_lyric_phrasing (Grob_info);
+ void add_voice_phrasing (Grob_info);
+};
+
+New_phrasing_engraver::New_phrasing_engraver()
+{
+
+}
+
+void
+New_phrasing_engraver::acknowledge_grob (Grob_info i)
+{
+ Grob *h = i.grob_;
+
+ if (Note_head::has_interface (h))
+ {
+ add_voice_phrasing (i);
+ }
+ else if (h->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
+ {
+ add_lyric_phrasing (i);
+ }
+}
+
+void
+New_phrasing_engraver::add_voice_phrasing (Grob_info inf)
+{
+ Translator_group * tr = inf.origin_trans_->daddy_trans_;
+ while (tr && !tr->is_alias (ly_symbol2scm ("Voice")))
+ tr = tr->daddy_trans_;
+
+ if (!tr)
+ return;
+
+ /*
+ should use dict?
+ */
+ Phrasing_association *a =0;
+ for (int i =0; !a && i < assocs_.size (); i++)
+ {
+ if (assocs_[i]->name_ == tr->id_string_)
+ a = assocs_[i];
+ }
+
+ if (!a)
+ {
+ a = new Phrasing_association ;
+ a->name_ = tr->id_string_;
+ assocs_.push (a);
+ }
+
+ a->heads_.push (inf.grob_);
+ a->melisma_ = melisma_busy (inf.origin_trans_);
+}
+
+void
+New_phrasing_engraver::add_lyric_phrasing (Grob_info inf)
+{
+ Translator_group * tr = inf.origin_trans_->daddy_trans_;
+ while (tr && !tr->is_alias (ly_symbol2scm ("LyricsVoice")))
+ tr = tr->daddy_trans_;
+
+ if (!tr)
+ return;
+
+ SCM voice = get_property ("associatedVoice");
+ String nm = tr->id_string_;
+ if (gh_string_p (voice))
+ nm = ly_scm2string (voice);
+ else
+ {
+ int idx = nm.index_last ('-');
+ if (idx >= 0)
+ nm = nm.left_string (idx);
+ }
+
+ Phrasing_association * a=0;
+ for (int i=0 ; !a && i < assocs_.size (); i++)
+ {
+ if (assocs_[i]->name_ == nm)
+ a = assocs_[i];
+ }
+
+ if (!a)
+ {
+ a = new Phrasing_association ;
+ a->name_ = nm;
+ assocs_.push (a);
+ }
+
+ a->lyrics_.push (inf.grob_);
+}
+
+void
+New_phrasing_engraver::stop_translation_timestep ()
+{
+ for (int i = assocs_.size (); i--; )
+ {
+ assocs_[i]->clear ();
+ assocs_[i]->last_melisma_ = assocs_[i]->melisma_;
+ }
+}
+
+void
+New_phrasing_engraver::process_acknowledged_grobs ()
+{
+ for (int i = 0; i < assocs_.size (); i++)
+ {
+ Phrasing_association * a = assocs_[i];
+ if (!a->heads_.size() || !a->lyrics_.size ())
+ continue;
+
+ Grob *h = a->heads_[0];
+ Direction alignment = CENTER;
+ if (a->melisma_ && !a->last_melisma_)
+ alignment = LEFT;
+
+ for (int j = 0; j < a->lyrics_.size (); j++)
+ {
+
+ Grob *l = a->lyrics_[j];
+ if (!l->get_parent (X_AXIS))
+ {
+ l->set_parent (h, X_AXIS);
+ if (alignment)
+ l->set_grob_property ("self-alignment-X", gh_int2scm (alignment));
+ }
+ }
+ }
+}
+
+New_phrasing_engraver::~New_phrasing_engraver ()
+{
+ for (int i =assocs_.size(); i--;)
+ delete assocs_[i];
+}
+
+ENTER_DESCRIPTION(New_phrasing_engraver,
+ "This engraver combines note heads and lyrics for alignment. ",
+ "",
+ "",
+ "lyric-syllable-interface note-head-interface lyric-extender-interface",
+ "automaticPhrasing associatedVoice",
+ "");
+
if (to_boolean (get_property ("followVoice")))
{
Translator_group * tr = daddy_trans_;
- while (tr && !tr->is_alias_b (ly_symbol2scm ( "Staff")))
+ while (tr && !tr->is_alias (ly_symbol2scm ( "Staff")))
tr = tr->daddy_trans_ ;
- if (tr && tr->is_alias_b (ly_symbol2scm ("Staff")) && tr != last_staff_)
+ if (tr && tr->is_alias (ly_symbol2scm ("Staff")) && tr != last_staff_)
{
if (last_head_)
follow_ = true;
Font_metric * fm = Font_interface::get_default_font (me);
Molecule out = fm->find_by_name (font_char);
- if (out.empty_b())
+ if (out.is_empty ())
{
me->warning (_f ("note head `%s' not found", font_char.to_str0 ()));
}
{
Molecule mol = internal_brew_molecule (me, false);
- if (!mol.empty_b())
+ if (!mol.is_empty ())
return mol.extent (a);
}
else
Box b = fm->get_indexed_char (k);
Offset wxwy = fm->get_indexed_wxwy (k);
Interval v = b[a];
- if (!v.empty_b ())
+ if (!v.is_empty ())
return 2 * (wxwy[a] - v.center()) / v.length ();
}
}
}
}
- if (extents[d].empty_b ())
+ if (extents[d].is_empty ())
extents[d] = Interval (0,0);
}
while (flip (&d) != LEFT);
FIXED also includes the left part of the right object.
*/
*fixed =
- (left_head_wid.empty_b () ? increment :
+ (left_head_wid.is_empty () ? increment :
/*
Size of the head:
*/
/*
What is sticking out of the right note:
*/
- + (extents[RIGHT].empty_b() ? 0.0 : - extents[RIGHT][LEFT] / 2);
+ + (extents[RIGHT].is_empty () ? 0.0 : - extents[RIGHT][LEFT] / 2);
/*
We don't do complicated stuff: (base_space - increment) is the
Real correction = 0.0;
- if (!bar_yextent.empty_b())
+ if (!bar_yextent.is_empty ())
{
stem_dirs[RIGHT] = - stem_dirs[LEFT];
stem_posns[RIGHT] = bar_yextent;
{
head_extent = head->extent (rcolumn, X_AXIS);
- if (!head_extent.empty_b())
+ if (!head_extent.is_empty ())
note_head_width = head_extent[RIGHT];
if (st)
{
intersect = stem_posns[LEFT];
intersect.intersect(stem_posns[RIGHT]);
- correct_stem_dirs = correct_stem_dirs && !intersect.empty_b ();
+ correct_stem_dirs = correct_stem_dirs && !intersect.is_empty ();
if (correct_stem_dirs)
{
gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
}
- if (!bar_yextent.empty_b())
+ if (!bar_yextent.is_empty ())
{
correction *= 0.5;
}
Interval hp = head_posns[LEFT];
hp.intersect (head_posns[RIGHT]);
- if (!hp.empty_b())
+ if (!hp.is_empty ())
return ;
Direction lowest =
If \translator Staff = bass, then look for Staff = *
*/
- while (current && !current->is_alias_b (to_type))
+ while (current && !current->is_alias (to_type))
{
last = current;
current = current->daddy_trans_;
thread level!
*/
- if (suffix_.empty_b ())
+ if (suffix_.is_empty ())
suffix_ = first_iter_->report_to ()
->daddy_trans_->id_string_.cut_string (3, INT_MAX);
Grob * r = unsmob_grob (rcol->get_grob_property ("rest"));
Interval restdim = r->extent (r, Y_AXIS); // ??
- if (restdim.empty_b ())
+ if (restdim.is_empty ())
return SCM_UNSPECIFIED;
Font_metric *fm = Font_interface::get_default_font (me);
String font_char = glyph_name (me, balltype, style);
Molecule out = fm->find_by_name (font_char);
- if (out.empty_b())
+ if (out.is_empty ())
{
me->warning (_f ("rest `%s' not found, ", font_char.to_str0 ()));
}
Grob *him = me->get_parent (a);
Interval he = him->extent (him,a);
- return gh_double2scm (he.empty_b () ? 0.0 : he.center ());
+ return gh_double2scm (he.is_empty () ? 0.0 : he.center ());
}
+MAKE_SCHEME_CALLBACK (Self_alignment_interface,aligned_on_parent,2);
+SCM
+Self_alignment_interface::aligned_on_parent (SCM element_smob, SCM axis)
+{
+ Grob *me = unsmob_grob (element_smob);
+ Axis a = (Axis) gh_scm2int (axis);
+ Grob *him = me->get_parent (a);
+ Interval he = him->extent (him,a);
+
+ SCM sym= (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X"): ly_symbol2scm ("self-alignment-Y");
+ SCM align_prop (me->internal_get_grob_property (sym));
+
+ if (!gh_number_p (align_prop))
+ return gh_int2scm (0);
+
+ Real x = 0.0;
+ Real align = gh_scm2double (align_prop);
+
+ Interval ext (me->extent (me,a));
+ if (ext.is_empty ())
+ {
+ programming_error ("I'm empty. Can't align on self");
+
+ }
+ else
+ x -= ext.linear_combination (align) ;
+
+ if (!he.is_empty ())
+ {
+ x += he.linear_combination (align);
+ }
+
+ return gh_double2scm (x);
+}
/*
Position centered on parent.
Grob *him = me->get_parent (other_axis (a));
Interval he = him->extent (him,a);
- return gh_double2scm (he.empty_b () ? 0.0 : he.center ());
+ return gh_double2scm (he.is_empty () ? 0.0 : he.center ());
}
{
Grob *me = unsmob_grob (element_smob);
Axis a = (Axis) gh_scm2int (axis);
- static SCM prop_syms[2];
- if (!prop_syms[0])
- {
- prop_syms[X_AXIS] = ly_symbol2scm ("self-alignment-X");
- prop_syms[Y_AXIS] = ly_symbol2scm ("self-alignment-Y");
- }
+ SCM sym= (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X"): ly_symbol2scm ("self-alignment-Y");
- SCM align (me->internal_get_grob_property (prop_syms[a]));
+ SCM align (me->internal_get_grob_property (sym));
if (gh_number_p (align))
{
Interval ext (me->extent (me,a));
- if (ext.empty_b ())
+ if (ext.is_empty ())
{
programming_error ("I'm empty. Can't align on self");
return gh_double2scm (0.0);
most cases, the interesting L will just be the first entry of
NEXT, making it linear in most of the cases.
*/
- if (Separation_item::width (r).empty_b ())
+ if (Separation_item::width (r).is_empty ())
return;
for(; gh_pair_p (next); next = ly_cdr (next))
{
Interval li (Separation_item::width (lb));
Interval ri (Separation_item::conditional_width (r, lb));
- if (!li.empty_b () && !ri.empty_b())
+ if (!li.is_empty () && !ri.is_empty ())
{
Rod rod;
Interval li (Separation_item::width (l));
Interval ri (Separation_item::conditional_width (r, l));
- if (!li.empty_b () && !ri.empty_b())
+ if (!li.is_empty () && !ri.is_empty ())
{
Rod rod;
}
Interval iv (il->extent (pc, X_AXIS));
- if (!iv.empty_b ())
+ if (!iv.is_empty ())
{
w.unite (iv);
}
}
}
- if (dim.empty_b ())
+ if (dim.is_empty ())
{
dim = Interval (0,0);
}
Interval iv = me->extent (me, a);
- if (!iv.empty_b ())
+ if (!iv.is_empty ())
{
if (!d)
{
Direction d)
{
Interval extent = b[line_axis];
- if (extent.empty_b())
+ if (extent.is_empty ())
return;
Real stick_out = b[other_axis (line_axis)][d];
Real my_height = line->elem(i).height_;
- if (!w.empty_b () &&
+ if (!w.is_empty () &&
w.length() > EPS
&& d* (my_height - stick_out) < 0)
{
Interval e1 (line->elem(i).width_[LEFT], extent[LEFT]);
Interval e3 (extent[RIGHT], line->elem(i).width_[RIGHT]);
- if (!e3.empty_b () && e3.length() > EPS)
+ if (!e3.is_empty () && e3.length() > EPS)
line->insert (Skyline_entry (e3, my_height), i+1);
line->elem_ref(i).height_ = stick_out;
line->elem_ref(i).width_ = w;
- if (!e1.empty_b () && e1.length() > EPS)
+ if (!e1.is_empty () && e1.length() > EPS)
line->insert (Skyline_entry (e1, my_height), i );
}
Interval w = buildings[i].width_;
w.intersect(clouds[j].width_);
- if (!w.empty_b())
+ if (!w.is_empty ())
distance = distance >? (buildings[i].height_ - clouds[j].height_);
if (i>0 && buildings[i].width_[LEFT] >= clouds[j].width_[LEFT])
o[X_AXIS] -= 0.5 * stem_dir * x_extent;
if ((stem_dir == dir)
- && !stem->extent (stem, Y_AXIS).empty_b ())
+ && !stem->extent (stem, Y_AXIS).is_empty ())
{
o[Y_AXIS] = stem->extent (common[Y_AXIS], Y_AXIS)[dir];
}
SCM smobbed_staff_bar = ly_car (elts);
Grob *staff_bar = unsmob_grob (smobbed_staff_bar);
Interval ext = staff_bar->extent (refp, Y_AXIS);
- if (ext.empty_b ())
+ if (ext.is_empty ())
continue;
- if (!prev_extent.empty_b ())
+ if (!prev_extent.is_empty ())
{
Interval l (prev_extent [UP],
ext[DOWN]);
- if (l.empty_b ())
+ if (l.is_empty ())
{
/* There is overlap between the bar lines. Do nothing. */
}
/* Bar_line::brew_molecule delivers a barline of y-extent (-h/2,h/2), so
we have to translate ourselves to be in the center of the
interval that we span. */
- if (i.empty_b ())
+ if (i.is_empty ())
{
me->suicide ();
return gh_double2scm (0.0);
{
Grob* me = unsmob_grob (smob);
Interval iv (get_spanned_interval (me));
- if (iv.empty_b ())
+ if (iv.is_empty ())
{
/* This happens if the bars are hara-kiried from under us. */
me->suicide ();
Let's decrease the space a little if the problem is not located
after a barline.
*/
- if (bar_size.empty_b ())
+ if (bar_size.is_empty ())
max_corr *= 0.75;
- if (!bar_size.empty_b())
+ if (!bar_size.is_empty ())
if (Grob *stem = Note_column::get_stem (g))
{
Direction d = Stem::get_direction (stem);
Interval ext = break_item->extent (col, X_AXIS);
- if (ext.empty_b ())
+ if (ext.is_empty ())
continue;
if (!last_grob
|| (last_grob && d * (ext[d]- (*last_ext)[d]) > 0) )
source file of the GNU LilyPond music typesetter
(c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>, Glen Prideaux <glenprideaux@iname.com>
-
- Similar to (and derived from) Instrument_name_engraver.
- */
+
+*/
#include "engraver.hh"
#include "item.hh"
-#include "bar-line.hh"
+#include "side-position-interface.hh"
class Stanza_number_engraver : public Engraver
{
Item *text_;
- bool bar_b_;
- void create_text (SCM s);
+ /*
+ This is naughty, since last_stanza_ may be GCd from under us. But
+ since we don't look at the contents, we are/should be (knock on
+ wood) OK.
+ */
+ SCM last_stanza_;
public:
TRANSLATOR_DECLARATIONS(Stanza_number_engraver);
-
virtual void process_music ();
virtual void stop_translation_timestep ();
+ virtual void acknowledge_grob (Grob_info);
};
+/*
+ TODO: should make engraver that collects all the stanzas on a higher
+ level, and then groups them to the side. Stanza numbers should be
+ all aligned.
+ */
Stanza_number_engraver::Stanza_number_engraver ()
{
text_ = 0;
- bar_b_ = false;
}
void
Stanza_number_engraver::process_music ()
{
- if (gh_string_p (get_property ("whichBar")))
+ SCM stanza = get_property ("stanza");
+
+ if (gh_string_p (stanza) && stanza != last_stanza_)
{
- SCM s = get_property ("stanza");
+ last_stanza_ = stanza;
- if (now_mom () > Moment (0))
- s = get_property ("stz");
-
-
- // TODO
- if (gh_string_p (s) || gh_pair_p (s))
-
- /*
- if (i.grob_->internal_has_interface (symbol ("lyric-syllable-interface")))
-
- Tried catching lyric items to generate stanza numbers, but it
- spoils lyric spacing.
-
- Works, but requires bar_engraver in LyricsVoice context apart
- from at beginning. Is there any score element we can catch
- that will do the trick?
-
- What happens if we try anything at all EXCEPT a lyric? Is
- there anything else? Not sure what it's catching, but it
- still mucks up lyrics.
-
- */
-
- create_text (s);
+ text_ = new Item (get_property ("StanzaNumber"));
+ text_->set_grob_property ("text", stanza);
+ announce_grob (text_, SCM_EOL);
}
}
+
void
-Stanza_number_engraver::stop_translation_timestep ()
+Stanza_number_engraver::acknowledge_grob (Grob_info inf)
{
- if (text_)
+ if (text_
+ && inf.grob_->internal_has_interface (ly_symbol2scm ("lyric-text-interface")))
{
- typeset_grob (text_);
- text_ = 0;
+ Side_position_interface::add_support (text_, inf.grob_);
}
}
void
-Stanza_number_engraver::create_text (SCM txt)
+Stanza_number_engraver::stop_translation_timestep ()
{
- if (!text_)
+ if (text_)
{
- text_ = new Item (get_property ("StanzaNumber"));
- text_->set_grob_property ("text", txt);
- announce_grob (text_, SCM_EOL);
+ typeset_grob (text_);
+ text_ = 0;
}
}
-
-
ENTER_DESCRIPTION(Stanza_number_engraver,
/* descr */ "",
/* creats*/ "StanzaNumber",
/* accepts */ "",
-/* acks */ "",
-/* reads */ "stz stanza",
+/* acks */ "lyric-syllable-interface",
+/* reads */ "stanza",
/* write */ "");
{
int staff_center = 0;
Interval hp = head_positions (me);
- if (hp.empty_b())
+ if (hp.is_empty ())
{
return CENTER;
}
if (durlog >= 3)
{
Interval flag_ext = flag (me).extent (Y_AXIS) ;
- if (!flag_ext.empty_b())
+ if (!flag_ext.is_empty ())
minlen += 2 * flag_ext.length () / ss ;
/*
flag_style + to_string (dir) + staffline_offs + to_string (duration_log (me));
Font_metric *fm = Font_interface::get_default_font (me);
Molecule flag = fm->find_by_name ("flags-" + font_char);
- if (flag.empty_b ())
+ if (flag.is_empty ())
{
me->warning (_f ("flag `%s' not found", font_char));
}
if (gh_string_p (stroke_style_scm))
{
String stroke_style = ly_scm2string (stroke_style_scm);
- if (!stroke_style.empty_b ())
+ if (!stroke_style.is_empty ())
{
String font_char = to_string (dir) + stroke_style;
Molecule stroke = fm->find_by_name ("flags-" + font_char);
- if (stroke.empty_b ())
+ if (stroke.is_empty ())
{
me->warning (_f ("flag stroke `%s' not found", font_char));
}
else
{
Path p = split_path (filename);
- if (!p.dir.empty_b ())
+ if (!p.dir.is_empty ())
if (mkdir (p.dir.to_str0 (), 0777) == -1 && errno != EEXIST)
error (_f ("can't create directory: `%s'", p.dir));
os = new std::ofstream (filename.to_str0 (), mode);
else
idx += String (&text.to_bytes ()[i], 1);
Molecule m = Font_interface::get_default_font (e)->find_by_name (idx);
- if (!m.empty_b ())
+ if (!m.is_empty ())
mol.add_at_edge (X_AXIS, RIGHT, m, 0, 0);
}
{
Interval v = unsmob_grob (gh_car (s))->extent (common, Y_AXIS);
- if (!v.empty_b ())
+ if (!v.is_empty ())
count ++;
}
(me->self_scm (), gh_int2scm (Y_AXIS)));
Real l = ext.length () / staff_space;
- if (ext.empty_b ()
+ if (ext.is_empty ()
|| (gh_number_p (c) && l <= gh_scm2double (c)))
{
me->suicide ();
{
int cmp = (lo + hi) / 2;
b = fm->get_indexed_char (cmp);
- if (b[Y_AXIS].empty_b () || b[Y_AXIS].length () > y)
+ if (b[Y_AXIS].is_empty () || b[Y_AXIS].length () > y)
hi = cmp;
else
lo = cmp;
}
Interval i (extent (this, Y_AXIS));
- if (i.empty_b ())
+ if (i.is_empty ())
programming_error ("Huh? Empty System?");
else
translate_axis (- i[MAX], Y_AXIS);
if (Text_item::markup_p (text))
edge[d] = *unsmob_molecule (Text_item::interpret_markup (paper->self_scm (), properties, text));
- if (!edge[d].empty_b ())
+ if (!edge[d].is_empty ())
edge[d].align_to (Y_AXIS, CENTER);
}
while (flip (&d) != LEFT);
m.add_molecule (edge[d]);
edge_line[d].translate_axis (span_points[d], X_AXIS);
m.add_molecule (edge_line[d]);
- if (!ext.empty_b ())
+ if (!ext.is_empty ())
span_points[d] += -d * ext[-d];
}
while (flip (&d) != LEFT);
me->set_grob_property ("font-family", ly_symbol2scm ("music"));
Molecule out = Font_interface::get_default_font (me)
->find_by_name ("timesig-" + char_name);
- if (!out.empty_b ())
+ if (!out.is_empty ())
return out;
/* If there is no such symbol, we default to the numbered style.
Translator_group::~Translator_group ()
{
- //assert (removable_b ());
+ //assert (is_removable ());
}
Translator_group *trg = dynamic_cast<Translator_group*> (unsmob_translator (ly_car (p)));
trg->check_removal ();
- if (trg->removable_b ())
+ if (trg->is_removable ())
terminate_translator (trg);
}
}
bool
-Translator_group::removable_b () const
+Translator_group::is_removable () const
{
return trans_group_list_ == SCM_EOL && ! iterator_count_;
}
Translator_group *
Translator_group::find_existing_translator (SCM n, String id)
{
- if ((is_alias_b (n) && (id_string_ == id || id.empty_b ())) || n == ly_symbol2scm ("Current"))
+ if ((is_alias (n) && (id_string_ == id || id.is_empty ())) || n == ly_symbol2scm ("Current"))
return this;
Translator_group* r = 0;
while (tr)
{
- if (tr->is_alias_b (name))
+ if (tr->is_alias (name))
return tr->self_scm();
tr = tr->daddy_trans_ ;
}
}
bool
-Translator::is_alias_b (SCM sym) const
+Translator::is_alias (SCM sym) const
{
Translator_def * td = unsmob_translator_def (definition_);
bool b = (sym == td->type_name_);
Virtual_font_metric::find_by_name (String glyph) const
{
Molecule m;
- for (SCM s = font_list_; m.empty_b () && gh_pair_p (s); s = gh_cdr (s))
+ for (SCM s = font_list_; m.is_empty () && gh_pair_p (s); s = gh_cdr (s))
{
m = unsmob_metrics (gh_car (s))->find_by_name (glyph);
}
{
Molecule m;
int total = 0;
- for (SCM s = font_list_; m.empty_b () && gh_pair_p (s); s = gh_cdr (s))
+ for (SCM s = font_list_; m.is_empty () && gh_pair_p (s); s = gh_cdr (s))
{
Font_metric *m =unsmob_metrics (gh_car (s));
int k = m->name_to_index (glyph);
\consists "Extender_engraver"
\consists "Hyphen_engraver"
\consists "Stanza_number_engraver"
+ \consists "Instrument_name_engraver"
\consists "Skip_event_swallow_translator"
phrasingPunctuation = #".,:!?\""
SeparationItem \set #'padding = #0.5
))
(LyricText
- . (
- (molecule-callback . ,Text_item::brew_molecule)
- (X-offset-callbacks . (,Self_alignment_interface::centered_on_parent
- ,Self_alignment_interface::aligned_on_self))
+ . ((molecule-callback . ,Text_item::brew_molecule)
+ (X-offset-callbacks . (,Self_alignment_interface::aligned_on_parent))
(self-alignment-X . 0)
(word-space . 0.6)
(ignore-length-mismatch . #f)
))
(StanzaNumber
- . (
- (breakable . #t)
- (molecule-callback . ,Text_item::brew_molecule)
- (break-align-symbol . clef)
- (break-visibility . ,begin-of-line-visible)
+ . ((molecule-callback . ,Text_item::brew_molecule)
(font-family . roman)
- (meta . ((interfaces . (break-aligned-interface text-interface font-interface item-interface ))))
+ (font-series . bold)
+ (padding . 1.5)
+ (X-offset-callbacks . (,Side_position_interface::aligned_side))
+ (direction . ,LEFT)
+ (meta . ((interfaces . (text-interface font-interface item-interface ))))
))
(StaffSpacing
(translator-property-description 'melismaBusyProperties list?
"List of properties (symbols) to
determine whether a melisma is playing.")
-(translator-property-description 'melismaEngraverBusy boolean? "See melismaBusy. This is set automatically.")
(translator-property-description 'metronomeMarkFormatter procedure?
"How to produce a metronome markup.
Called with 2 arguments, event and context.")
(translator-property-description 'stringOneTopmost boolean? "Whether the 1st string is printed on the
top line of the tablature.")
(translator-property-description 'stavesFound list? "list of all staff-symbols found.")
-(translator-property-description 'stanza markup? "Stanza `number' to print at start of a verse. Use in LyricsVoice context.")
+(translator-property-description 'stanza markup? "Stanza `number' to
+print before the start of a verse. Use in LyricsVoice context.")
(translator-property-description 'stemLeftBeamCount integer? "
Specify the number of beams to draw on the left side of the next note.
Overrides automatic beaming. The value is only used once, and then it
.")
(translator-property-description 'stemRightBeamCount integer? "idem, for the right side.")
(translator-property-description 'stringTunings list? "The tablature strings tuning. Must be a list of the different semitons pitch of each string (starting by the lower one).")
-(translator-property-description 'stz markup? "Abbreviated form for a stanza, see also Stanza property.")
(translator-property-description 'subdivideBeams boolean? "If set, multiple beams will be subdivided at beat
positions - by only drawing one beam over the beat.")
(translator-property-description 'systemStartDelimiter symbol? "Which grob to make for the start of the system/staff?")
conversions.append (((2,1,2), conv, """ly:get-music-length -> ly:music-length"""))
+def conv (str):
+ str =re.sub (r"\.\s+stz=", ". instr ", str)
+ return str
+
+conversions.append (((2,1,2), conv, """ly:get-music-length -> ly:music-length"""))
+
################################
# END OF CONVERSIONS
################################