diff options
author | Han-Wen Nienhuys <hanwen@xs4all.nl> | 2004-01-13 11:24:14 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@xs4all.nl> | 2004-01-13 11:24:14 +0000 |
commit | b9fc4bb5b3ce7d75e7e5284352eeaa04bbe78e14 (patch) | |
tree | 63301994feb2eac5005766dddaf25c24e2bc8d42 | |
parent | 33e47ae098ad73db17bc1cbcc4f0c4dd4bb9714f (diff) |
* mf/feta18.mf: design size is 18 not 22.5
* lily/new-lyric-combine-music-iterator.cc (process): new file.
Add a single LyricsVoice to a melody. Melismata may be set
individually.
* input/regression/lyric-combine-new.ly: new file. Demo \newaddlyrics.
* lily/dot-column.cc: add stdio.h
27 files changed, 384 insertions, 40 deletions
@@ -1,3 +1,19 @@ +2004-01-13 Han-Wen Nienhuys <hanwen@xs4all.nl> + + * mf/feta18.mf: design size is 18 not 22.5 + + * lily/new-lyric-combine-music-iterator.cc (process): new file. + Add a single LyricsVoice to a melody. Melismata may be set + individually. + + * input/regression/lyric-combine-new.ly: new file. Demo \newaddlyrics. + + * lily/dot-column.cc: add stdio.h + +2004-01-12 Han-Wen Nienhuys <hanwen@xs4all.nl> + + * lily/item.cc: documentation for break-visibility (Thanks, John). + 2004-01-11 Han-Wen Nienhuys <hanwen@xs4all.nl> * lily/bar-line.cc (compound_barline): add bartype : (dotted). diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index d082a8a761..1d67d864f3 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -1123,7 +1123,8 @@ c4 \bar ":|" c \bar ".|" c \bar ".|." c -\bar "|." +\bar "|." c +\bar ":" c @end lilypond For allowing linebreaks, there is a special command, @example @@ -1171,9 +1172,9 @@ You are encouraged to use @code{\repeat} for repetitions. See In this manual: @ref{Repeats}. -The bar line objects that are created at @internalsref{Staff} level -are called @internalsref{BarLine}, the bar lines that span staves are -@internalsref{SpanBar}s. +Internals: the bar line objects that are created at +@internalsref{Staff} level are called @internalsref{BarLine}, the bar +lines that span staves are @internalsref{SpanBar}s. @cindex bar lines at start of system @cindex start of system @@ -1184,6 +1185,8 @@ The barlines at the start of each system are in every context, and that type is determined by the property @code{systemStartDelimiter}. +Examples: @inputfileref{input/test,bar-lines.ly}, + @node Polyphony @section Polyphony @cindex polyphony diff --git a/flower/include/rational.hh b/flower/include/rational.hh index 1ba68a35b3..3cb5fb5d1b 100644 --- a/flower/include/rational.hh +++ b/flower/include/rational.hh @@ -35,10 +35,7 @@ class Rational { public: void set_infinite (int sign); - bool infty_b () const - { - return sign_ == 2 || sign_ == -2; - } + bool is_infinity () const; void invert (); int num () const { return sign_ * num_; } int den () const { return den_; } diff --git a/flower/rational.cc b/flower/rational.cc index c5019afbd5..f238e4b30d 100644 --- a/flower/rational.cc +++ b/flower/rational.cc @@ -143,7 +143,7 @@ Rational::compare (Rational const &r, Rational const &s) return -1; else if (r.sign_ > s.sign_) return 1; - else if (r.infty_b ()) + else if (r.is_infinity ()) return 0; else if (r.sign_ == 0) return 0; @@ -169,9 +169,9 @@ Rational::operator %= (Rational r) Rational & Rational::operator += (Rational r) { - if (infty_b ()) + if (is_infinity ()) ; - else if (r.infty_b ()) + else if (r.is_infinity ()) { *this = r; } @@ -242,7 +242,7 @@ Rational & Rational::operator *= (Rational r) { sign_ *= ::sign (r.sign_); - if (r.infty_b ()) + if (r.is_infinity ()) { sign_ = sign () * 2; goto exit_func; @@ -279,7 +279,7 @@ Rational::operator -= (Rational r) String Rational::to_string () const { - if (infty_b ()) + if (is_infinity ()) { String s (sign_ > 0 ? "" : "-" ); return String (s + "infinity"); @@ -302,3 +302,9 @@ sign (Rational r) { return r.sign (); } + +bool +Rational::is_infinity () const +{ + return sign_ == 2 || sign_ == -2; +} diff --git a/input/regression/lyric-combine-new.ly b/input/regression/lyric-combine-new.ly new file mode 100644 index 0000000000..e075cd7785 --- /dev/null +++ b/input/regression/lyric-combine-new.ly @@ -0,0 +1,30 @@ +\header { + + texidoc = "With the newaddlyrics mechanism, individual lyric lines + can be associated with one melody line. For each lyric line, can + be tuned whether to follow melismata or not." + +} + +\score { +<< + \notes \context Voice = "bla" \relative c'' { + c2( d4) e4 ( c2 d4) e4 + } + \newaddlyrics "bla" \lyrics \new LyricsVoice { bla ab blob blob } + \newaddlyrics "bla" + \lyrics \new LyricsVoice { + bla + + \property LyricsVoice . ignoreMelismata = ##t + + blob + + %% note: effect of ignoreMelismata delayed one time step. + \property LyricsVoice . ignoreMelismata \unset + blob + + blob + } + >> + } diff --git a/input/regression/molecule-hacking.ly b/input/regression/molecule-hacking.ly index 8bb9dbcc7b..21d3077b5d 100644 --- a/input/regression/molecule-hacking.ly +++ b/input/regression/molecule-hacking.ly @@ -16,7 +16,7 @@ parens are also not seen by accidentals. "Construct a function that will do CALLBACK and add parentheses. Example usage: - \property Voice.NoteHead \\override #'molecule-callback + \\property Voice.NoteHead \\override #'molecule-callback = #(parenthesize-callback Note_head::brew_molecule) diff --git a/lily/dot-column.cc b/lily/dot-column.cc index beff0f4f0f..f74c6451ae 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -6,7 +6,7 @@ (c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl> */ -#include <set> +#include <stdio.h> #include <map> #include "dots.hh" @@ -19,8 +19,6 @@ #include "axis-group-interface.hh" #include "stem.hh" -using std::set; - /* TODO: let Dot_column communicate with stem via Note_column. */ diff --git a/lily/include/interpretation-context-handle.hh b/lily/include/interpretation-context-handle.hh index 80db970f45..6ab87d4064 100644 --- a/lily/include/interpretation-context-handle.hh +++ b/lily/include/interpretation-context-handle.hh @@ -22,7 +22,7 @@ public: void operator = (Interpretation_context_handle const&); Interpretation_context_handle (Interpretation_context_handle const&); Translator_group * report_to () const; - + int get_count () const; void quit (); private: Translator_group * report_to_; diff --git a/lily/include/music-iterator.hh b/lily/include/music-iterator.hh index bc1e63ef96..e49777a659 100644 --- a/lily/include/music-iterator.hh +++ b/lily/include/music-iterator.hh @@ -95,6 +95,8 @@ void quit (); virtual Moment pending_moment () const; virtual bool ok () const; + + virtual bool run_always () const; virtual SCM get_pending_events (Moment until)const; virtual void process (Moment until); virtual void skip (Moment until); diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh index 4a1a10c361..7703529da1 100644 --- a/lily/include/translator-group.hh +++ b/lily/include/translator-group.hh @@ -56,15 +56,12 @@ public: void add_fresh_group_translator (Translator *trans); void add_used_group_translator (Translator *trans); - /// Score_register = 0, Staff_registers = 1, etc) - Translator_group* get_ancestor (int l=1); int get_depth () const; bool is_bottom_translator_b () const; bool is_removable () const; void terminate_translator (Translator*r); Translator *remove_translator (Translator*trans); void check_removal (); - // Translator *get_simple_translator (String) const; Translator_group *find_existing_translator (SCM context_name, String id); Translator_group *find_create_translator (SCM context_name, String id, SCM ops); Link_array<Translator_group> path_to_acceptable_translator (SCM alias, diff --git a/lily/interpretation-context-handle.cc b/lily/interpretation-context-handle.cc index ef840ebf9a..dee2951851 100644 --- a/lily/interpretation-context-handle.cc +++ b/lily/interpretation-context-handle.cc @@ -95,4 +95,8 @@ Interpretation_context_handle::report_to ()const return report_to_; } - +int +Interpretation_context_handle::get_count ()const +{ + return report_to_->iterator_count_ ; +} diff --git a/lily/item.cc b/lily/item.cc index 89eb804389..64d6c39637 100644 --- a/lily/item.cc +++ b/lily/item.cc @@ -212,5 +212,18 @@ ADD_INTERFACE(Item, "the outcome of the @code{break-visibility}. This grob property is a\n" "function taking a direction (-1, 0 or 1) as argument. It returns a\n" "cons of booleans, signifying whether this grob should be transparent\n" - "and have no extent.\n", + "and have no extent.\n" + "\n" + "The following variables for break-visibility are predefined:\n" + "@example\n" + " grob will show: before no after\n" + " break break break\n" + " all-invisible no no no\n" + " begin-of-line-visible no no yes\n" + " end-of-line-visible yes no no\n" + " all-visible yes yes yes\n" + " begin-of-line-invisible yes yes no\n" + " end-of-line-invisible no yes yes\n" + "@end example\n" + , "no-spacing-rods break-visibility breakable") diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc index b7e5f75ff7..f33a10de35 100644 --- a/lily/lyric-phrasing-engraver.cc +++ b/lily/lyric-phrasing-engraver.cc @@ -91,6 +91,12 @@ Lyric_phrasing_engraver::get_phrasing_assoc (String nm) String Lyric_phrasing_engraver::get_voice_name_for_lyric (Translator_group*tr) { + SCM voice_context = tr->get_property ("associatedVoiceContext"); + if (Translator *vc = unsmob_translator (voice_context)) + { + return dynamic_cast<Translator_group*> (vc)->id_string_; + } + SCM voice = tr->get_property ("associatedVoice"); String nm = tr->id_string_; if (gh_string_p (voice)) diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc index 9964be5b7b..d70fec3d2b 100644 --- a/lily/music-iterator.cc +++ b/lily/music-iterator.cc @@ -230,3 +230,9 @@ void Music_iterator::do_quit() { } + +bool +Music_iterator::run_always ()const +{ + return false; +} diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 43b5a5cc18..61da4ba258 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -59,6 +59,7 @@ static Keyword_ent the_key_tab[]={ {"midi", MIDI}, {"name", NAME}, {"new", NEWCONTEXT}, + {"newaddlyrics", NEWADDLYRICS}, {"notes", NOTES}, {"octave", OCTAVE}, {"once", ONCE}, diff --git a/lily/new-lyric-combine-music-iterator.cc b/lily/new-lyric-combine-music-iterator.cc new file mode 100644 index 0000000000..77f5e43fe8 --- /dev/null +++ b/lily/new-lyric-combine-music-iterator.cc @@ -0,0 +1,226 @@ +/* +new-lyric-combine-iterator.cc -- implement New_lyric_combine_music_iterator + +source file of the GNU LilyPond music typesetter + +(c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl> + + */ + +#include "translator-group.hh" +#include "lyric-combine-music.hh" +#include "event.hh" +#include "grob.hh" +#include "music-iterator.hh" + + +class New_lyric_combine_music_iterator : public Music_iterator +{ +public: + VIRTUAL_COPY_CONS (Music_iterator); + New_lyric_combine_music_iterator (); + New_lyric_combine_music_iterator (New_lyric_combine_music_iterator const&src); + DECLARE_SCHEME_CALLBACK(constructor, ()); +protected: + virtual void construct_children (); + virtual Moment pending_moment () const; + virtual void do_quit(); + virtual void process (Moment); + virtual Music_iterator *try_music_in_children (Music *) const; + virtual bool run_always ()const; + virtual bool ok () const; + virtual void derived_mark () const; +private: + bool start_new_syllable () ; + + Translator_group * lyrics_context_; + Translator_group* music_context_; + Music_iterator * lyric_iter_; +}; + +/* + Ugh, why static? + */ +static Music *busy_ev; +static Music *start_ev; +static Music *melisma_playing_ev; + +New_lyric_combine_music_iterator::New_lyric_combine_music_iterator () +{ + lyric_iter_ =0; + music_context_ =0; + lyrics_context_ = 0; + if (!busy_ev) + { + busy_ev + = make_music_by_name (ly_symbol2scm ("BusyPlayingEvent")); + start_ev + = make_music_by_name (ly_symbol2scm ("StartPlayingEvent")); + melisma_playing_ev + = make_music_by_name (ly_symbol2scm ("MelismaPlayingEvent")); + } +} + +bool +New_lyric_combine_music_iterator::start_new_syllable () +{ + bool b = music_context_->try_music (busy_ev); + + if (!b) + return false; + + if (!to_boolean (lyrics_context_->get_property ("ignoreMelismata"))) + { + bool m = music_context_->try_music (melisma_playing_ev); + if (m) + return false; + } + + return true; +} + +Moment +New_lyric_combine_music_iterator::pending_moment () const +{ + Moment m; + + m.set_infinite (1); + + return m; +} + +bool +New_lyric_combine_music_iterator::run_always () const +{ + return true; +} + +bool +New_lyric_combine_music_iterator::ok () const +{ + return music_context_ && lyric_iter_->ok (); +} + +void +New_lyric_combine_music_iterator::derived_mark()const +{ + if (lyric_iter_) + scm_gc_mark (lyric_iter_->self_scm ()); + if (lyrics_context_) + scm_gc_mark (lyrics_context_->self_scm ()); + if (music_context_) + scm_gc_mark (music_context_->self_scm ()); +} + +/* + ID == "" means accept any ID. + */ +Translator_group * +find_context_below (Translator_group * where, + String type, String id) +{ + if (where->context_name () == type) + { + if (id == "" || where->id_string_ == id) + return where; + } + + Translator_group * found = 0; + for (SCM s = where->trans_group_list_; + !found && gh_pair_p (s); s = gh_cdr (s)) + { + Translator_group * tr = dynamic_cast<Translator_group*> (unsmob_translator (gh_car (s))); + + + found = find_context_below (tr, type, id); + } + + return found; +} + + + +void +New_lyric_combine_music_iterator::construct_children () +{ + Music *m = unsmob_music (get_music ()->get_mus_property ("element")); + lyric_iter_ = unsmob_iterator (get_iterator (m)); + + SCM voice_name = get_music ()->get_mus_property ("associated-context"); + + + Translator_group * thread = 0, *voice =0; + + if (gh_string_p (voice_name)) + { + Translator_group *t = report_to (); + while (t && t->daddy_trans_) + t = t->daddy_trans_; + + voice = find_context_below (t, "Voice", ly_scm2string (voice_name)); + if (voice) + thread = find_context_below (voice, "Thread", ""); + } + + if (thread) + { + music_context_ = thread; + lyrics_context_ = find_context_below (lyric_iter_->report_to (), "LyricsVoice", ""); + + if (lyrics_context_) + lyrics_context_->set_property ("associatedVoiceContext", voice->self_scm ()); + } +} + +void +New_lyric_combine_music_iterator::process (Moment ) +{ + if (!music_context_->daddy_trans_) + { + music_context_ = 0; + if (lyrics_context_) + lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext")); + } + + if (music_context_ + && start_new_syllable () && lyric_iter_->ok ()) + { + Moment m= lyric_iter_->pending_moment (); + lyric_iter_->process (m); + } +} + +void +New_lyric_combine_music_iterator::do_quit () +{ + if (lyric_iter_) + lyric_iter_->quit(); +} + +New_lyric_combine_music_iterator::New_lyric_combine_music_iterator (New_lyric_combine_music_iterator const & src) + : Music_iterator (src) +{ + lyric_iter_ = 0; + + if (src.lyric_iter_) + lyric_iter_ = src.lyric_iter_->clone (); + + if (lyric_iter_) + scm_gc_unprotect_object (lyric_iter_->self_scm()); + + music_context_ = src.music_context_; + lyric_iter_ = src.lyric_iter_; + + + assert (false); // shouldn't copy, really. +} + + +Music_iterator* +New_lyric_combine_music_iterator::try_music_in_children (Music *m) const +{ + return lyric_iter_->try_music (m); +} + + +IMPLEMENT_CTOR_CALLBACK (New_lyric_combine_music_iterator); diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index 0f0c820135..7900585763 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -50,6 +50,8 @@ Note_heads_engraver::try_music (Music *m) } else if (m->is_mus_type ("busy-playing-event")) return note_reqs_.size (); + else if (m->is_mus_type ("start-playing-event")) + return note_reqs_.size (); return false; } diff --git a/lily/parser.yy b/lily/parser.yy index 4bcf3b7d5d..9018962644 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -238,6 +238,7 @@ yylex (YYSTYPE *s, void * v) %token ACCEPTS %token ADDLYRICS +%token NEWADDLYRICS %token ALIAS %token ALTERNATIVE %token APPLY @@ -1097,6 +1098,13 @@ re_rhythmed_music: scm_gc_unprotect_object ($2->self_scm ()); $$ = l; } + | NEWADDLYRICS string Music { + Music*l =MY_MAKE_MUSIC("NewLyricCombineMusic"); + l->set_mus_property ("element", $3->self_scm ()); + scm_gc_unprotect_object ($3->self_scm ()); + $$ = l; + l->set_mus_property ("associated-context", $2); + } ; part_combined_music: diff --git a/lily/simultaneous-music-iterator.cc b/lily/simultaneous-music-iterator.cc index 84008b6b11..b875668ef7 100644 --- a/lily/simultaneous-music-iterator.cc +++ b/lily/simultaneous-music-iterator.cc @@ -105,7 +105,8 @@ Simultaneous_music_iterator::process (Moment until) while(gh_pair_p (*proc)) { Music_iterator * i = unsmob_iterator (gh_car (*proc)); - if (i->pending_moment () == until) + if (i->run_always () + || i->pending_moment () == until) { i->process (until); } @@ -151,16 +152,24 @@ Simultaneous_music_iterator::pending_moment () const next.set_infinite (1); for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s)) - next = next <? unsmob_iterator (gh_car (s))->pending_moment () ; + { + Music_iterator * it = unsmob_iterator (gh_car (s)); + if (!it-> run_always ()) + next = next <? it->pending_moment (); + } return next; } - - bool Simultaneous_music_iterator::ok () const { - return gh_pair_p (children_list_); + for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s)) + { + Music_iterator * it = unsmob_iterator (gh_car (s)); + if (!it->run_always ()) + return true; + } + return false; } Music_iterator* diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 14d7699d78..c582357f72 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -445,7 +445,7 @@ Spacing_spanner::find_shortest (Grob *me, Link_array<Grob> const &cols) assert (this_shortest.to_bool()); shortest_in_measure = shortest_in_measure <? this_shortest.main_part_; } - else if (!shortest_in_measure.infty_b() + else if (!shortest_in_measure.is_infinity () && Item::breakable_b (cols[i])) { int j = 0; diff --git a/lily/timing-translator.cc b/lily/timing-translator.cc index 3d83282c6c..aa8e7e2723 100644 --- a/lily/timing-translator.cc +++ b/lily/timing-translator.cc @@ -117,6 +117,11 @@ Timing_translator::start_translation_timestep () programming_error ("Moving backwards in time"); dt = 0; } + else if (dt.main_part_.is_infinity ()) + { + programming_error ("Moving infinitely to future"); + dt = 0; + } if (!dt.to_bool ()) return; diff --git a/lily/translator-group.cc b/lily/translator-group.cc index a8dbae57cd..503f2a7b47 100644 --- a/lily/translator-group.cc +++ b/lily/translator-group.cc @@ -188,15 +188,6 @@ Translator_group::get_depth () const return (daddy_trans_) ? daddy_trans_->get_depth () + 1 : 0; } -Translator_group* -Translator_group::get_ancestor (int level) -{ - if (!level || !daddy_trans_) - return this; - - return daddy_trans_->get_ancestor (level-1); -} - void Translator_group::terminate_translator (Translator*r) { diff --git a/mf/feta18.mf b/mf/feta18.mf index 3b77b766d7..1fa053e169 100644 --- a/mf/feta18.mf +++ b/mf/feta18.mf @@ -4,7 +4,7 @@ input feta-autometric; % todo change file name -fet_beginfont("feta", 22.5); +fet_beginfont("feta", 18); staffsize#:=17.82pt#; test:=0; diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 1e61027221..0fa1c14207 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -459,6 +459,10 @@ Like @code{bracket-visibility}, but for the number.") (grob-property-description 'break-visibility procedure? "a function that takes the break direction and returns a cons of booleans containing (TRANSPARENT . EMPTY). +The following variables are predefined: @code{all-visible}, +@code{begin-of-line-visible}, @code{end-of-line-visible}, +@code{begin-of-line-invisible}, @code{end-of-line-invisible}, +@code{all-invisible}. ") (grob-property-description 'virga boolean? "is this neume a virga?.") diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index f994902fc0..2a2bd790dd 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -112,6 +112,13 @@ c8-[ c c-] c8") (internal-class-name . "Event") (types . (general-music event busy-playing-event)) )) + (StartPlayingEvent + . ( + (description . "Used internally to signal beginning of notes.") + + (internal-class-name . "Event") + (types . (general-music event start-playing-event)) + )) (ClusterNoteEvent . ( @@ -215,6 +222,16 @@ Syntax @var{\\addlyrics }@var{music} @var{lyrics}.") (types . (general-music lyric-combine-music)) (iterator-ctor . ,Lyric_combine_music_iterator::constructor) )) + + (NewLyricCombineMusic + . ( + (description . "Align lyrics to the start of notes. +Syntax @var{\\addlyrics }@var{music} @var{lyrics}.") + (internal-class-name . "Music") + (length . ,(ly:make-moment 0 1)) + (types . (general-music lyric-combine-music)) + (iterator-ctor . ,New_lyric_combine_music_iterator::constructor) + )) (LyricEvent . ( diff --git a/scm/define-translator-properties.scm b/scm/define-translator-properties.scm index 6df9e9bf92..9157745d94 100644 --- a/scm/define-translator-properties.scm +++ b/scm/define-translator-properties.scm @@ -270,6 +270,9 @@ function.") (translator-property-description 'highStringOne boolean? "Whether the 1st string is the string with highest pitch on the instrument (used by the automatic string selector).") + +(translator-property-description 'ignoreMelismata boolean? + "Ignore melismata for this @ref{LyricsVoice}.") (translator-property-description 'instr markup? "see @code{instrument}") (translator-property-description 'instrument markup? " If @code{Instrument_name_engraver} @cindex Instrument_name_engraver diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py index daf03fd202..91fd16942c 100644 --- a/scripts/convert-ly.py +++ b/scripts/convert-ly.py @@ -1635,7 +1635,7 @@ def conv (str): if c == 'Score': return '' else: - return r"\unset \property %s.melismaBusyProperties" % c + return r" \property %s.melismaBusyProperties \unset" % c elif b == 'f': return r"\property %s.melismaBusyProperties = #'(melismaBusy)" % c |