]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/lyric-phrasing-engraver.cc
''
[lilypond.git] / lily / lyric-phrasing-engraver.cc
index e5d5855b4e4c1e84b333c3a137f1f4f72959e797..23b8fd4cdcd2e40b4c66388c8b3cd1858c3e0df2 100644 (file)
@@ -31,13 +31,13 @@ String trim_suffix (String &id);
 
   
 
-> About lyrics, it happens that there are common words for many bars, like
-> for a refrain say.  When there is an even number of lyrics lines, I do not
-> know how to force the positioning of the common lyric line in the plain
-> middle of the others, because this is in between lines.  Not a big matter,
-> but it would be a bit nicer if this was doable.
+  > About lyrics, it happens that there are common words for many bars, like
+  > for a refrain say.  When there is an even number of lyrics lines, I do not
+  > know how to force the positioning of the common lyric line in the plain
+  > middle of the others, because this is in between lines.  Not a big matter,
+  > but it would be a bit nicer if this was doable.
 
- */
+*/
 
 /*
   We find start and end of phrases, and align lyrics of multiple stanzas
@@ -48,11 +48,11 @@ String trim_suffix (String &id);
   that seems to be the case now -- jcn)
 
 
-          |        |        |     |      |
-         x|       x|       x|    x|     x|
+  |        |        |     |      |
+  x|       x|       x|    x|     x|
 
-     1:  Start  sentence  melisma      end.
-     2:  x         x         x_____       x
+  1:  Start  sentence  melisma      end.
+  2:  x         x         x_____       x
 
   Only lyrics that are followed by '__' while there's a melisma,
   are left-aligned, in this case the third x.
@@ -61,20 +61,20 @@ String trim_suffix (String &id);
   Alignment and melismata
 
   I've taken [a different] approach:
-         |      |
-         |      |
-        O      O  <-- second note throws a melisma score element
-         \____/
+  |      |
+  |      |
+  O      O  <-- second note throws a melisma score element
+  \____/
 
-        ^      ^
-        |      |
-       Lyric (None)
+  ^      ^
+  |      |
+  Lyric (None)
 
   Lyric_phrasing_engraver keeps track of the current and previous notes and
   lyrics for each voice, and when it catches a melisma, it adjusts the
   alignment of the lyrics of the previous note. I hope this isn't
   unnecessarily convoluted.
- */
+*/
 
 Lyric_phrasing_engraver::Lyric_phrasing_engraver ()
 {
@@ -86,7 +86,7 @@ Lyric_phrasing_engraver::~Lyric_phrasing_engraver ()
 {
   /*
     No need to delete alist_; that's what Garbage collection is for.
-   */
+  */
 }
 
 void
@@ -94,7 +94,7 @@ Lyric_phrasing_engraver::finalize ()
 {
   /*
     but do need to unprotect alist_, since Engravers are gc'd now.
-   */
+  */
 
   voice_alist_ = SCM_EOL;
 }
@@ -104,25 +104,28 @@ Syllable_group *
 Lyric_phrasing_engraver::lookup_context_id (const String &context_id)
 {
   SCM key = ly_str02scm (context_id.ch_C ());
-  if (! gh_null_p (voice_alist_)) {
-    SCM s = scm_assoc (key, voice_alist_);
-    if (! (gh_boolean_p (s) && !to_boolean (s))) {
-      /* match found */
-      // (key . ((alist_entry . old_entry) . previous_entry))
-      if (to_boolean (ly_cdadr (s))) { // it's an old entry ... make it a new one
-       SCM val = gh_cons (gh_cons (ly_caadr (s), SCM_BOOL_F), ly_cddr (s)); 
-       voice_alist_ = scm_assoc_set_x (voice_alist_, ly_car (s), val);
-       return unsmob_voice_entry (ly_caar (val));
-      }
-      else { // the entry is current ... return it.
-       SCM entry_scm = ly_caadr (s);
-       return unsmob_voice_entry (entry_scm);
-      }
+  if (! gh_null_p (voice_alist_))
+    {
+      SCM s = scm_assoc (key, voice_alist_);
+      if (! (gh_boolean_p (s) && !to_boolean (s)))
+       {
+         /* match found */
+         // (key . ((alist_entry . old_entry) . previous_entry))
+         if (to_boolean (ly_cdadr (s)))
+           { // it's an old entry ... make it a new one
+             SCM val = gh_cons (gh_cons (ly_caadr (s), SCM_BOOL_F), ly_cddr (s)); 
+             voice_alist_ = scm_assoc_set_x (voice_alist_, ly_car (s), val);
+             return unsmob_voice_entry (ly_caar (val));
+           }
+         else { // the entry is current ... return it.
+           SCM entry_scm = ly_caadr (s);
+           return unsmob_voice_entry (entry_scm);
+         }
+       }
     }
-  }
   // ((alist_entry . old_entry) . previous_entry)
   SCM val = gh_cons (gh_cons (Syllable_group::make_entry (), SCM_BOOL_F), 
-                   Syllable_group::make_entry ()); 
+                    Syllable_group::make_entry ()); 
 
   voice_alist_ = scm_acons (key, val, voice_alist_);
   return unsmob_voice_entry (ly_caar (val));
@@ -131,7 +134,7 @@ Lyric_phrasing_engraver::lookup_context_id (const String &context_id)
 
 void 
 Lyric_phrasing_engraver::record_notehead (const String &context_id, 
-                                        Grob * notehead)
+                                         Grob * notehead)
 {
   Syllable_group * v = lookup_context_id (context_id);
   v->set_notehead (notehead);
@@ -150,18 +153,21 @@ void
 Lyric_phrasing_engraver::record_extender (const String &context_id, Grob * extender)
 {
   SCM key = ly_str02scm (context_id.ch_C ());
-  if (! gh_null_p (voice_alist_)) {
-    SCM s = scm_assoc (key, voice_alist_);
-    if (! (gh_boolean_p (s) && !to_boolean (s))) {
-      /* match found */
-      // (key . ((alist_entry . old_entry) . previous_entry))
-      SCM previous_scm = ly_cddr (s);
-      if (previous_scm != SCM_EOL) {
-       Syllable_group * v = unsmob_voice_entry (previous_scm);
-       v->add_extender (extender);
-      }
+  if (! gh_null_p (voice_alist_))
+    {
+      SCM s = scm_assoc (key, voice_alist_);
+      if (! (gh_boolean_p (s) && !to_boolean (s)))
+       {
+         /* match found */
+         // (key . ((alist_entry . old_entry) . previous_entry))
+         SCM previous_scm = ly_cddr (s);
+         if (previous_scm != SCM_EOL)
+           {
+             Syllable_group * v = unsmob_voice_entry (previous_scm);
+             v->add_extender (extender);
+           }
+       }
     }
-  }
 }
 
 void 
@@ -181,36 +187,40 @@ Lyric_phrasing_engraver::acknowledge_grob (Grob_info i)
 
   Grob *h = i.grob_l_;
 
-  if (Note_head::has_interface (h)) {
-    /* caught a note head ... do something with it */
+  if (Note_head::has_interface (h))
+    {
+      /* caught a note head ... do something with it */
 
-    /* what's its Voice context name? */
-    String voice_context_id = get_context_id (i.origin_trans_l_->daddy_trans_l_, "Voice");
-    record_notehead (voice_context_id, h);
+      /* what's its Voice context name? */
+      String voice_context_id = get_context_id (i.origin_trans_l_->daddy_trans_l_, "Voice");
+      record_notehead (voice_context_id, h);
 
-    /* is it in a melisma ? */
-    if (to_boolean (i.origin_trans_l_->get_property ("melismaEngraverBusy"))) {
-      record_melisma (voice_context_id);
+      /* is it in a melisma ? */
+      if (to_boolean (i.origin_trans_l_->get_property ("melismaEngraverBusy")))
+       {
+         record_melisma (voice_context_id);
+       }
+      return;
     }
-    return;
-  }
 
   /* now try for a lyric */
-  if (h->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface"))) {
-
-    /* what's its LyricsVoice context name? */
-    String voice_context_id;
-    SCM voice_context_scm = i.origin_trans_l_->get_property ("associatedVoice");
-    if (gh_string_p (voice_context_scm)) {
-      voice_context_id = ly_scm2string (voice_context_scm);
-    }
-    else {
-      voice_context_id = get_context_id (i.origin_trans_l_->daddy_trans_l_, "LyricsVoice");
-      voice_context_id = trim_suffix (voice_context_id);
+  if (h->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
+    {
+
+      /* what's its LyricsVoice context name? */
+      String voice_context_id;
+      SCM voice_context_scm = i.origin_trans_l_->get_property ("associatedVoice");
+      if (gh_string_p (voice_context_scm))
+       {
+         voice_context_id = ly_scm2string (voice_context_scm);
+       }
+      else {
+       voice_context_id = get_context_id (i.origin_trans_l_->daddy_trans_l_, "LyricsVoice");
+       voice_context_id = trim_suffix (voice_context_id);
+      }
+      record_lyric (voice_context_id, h);
+      return;
     }
-    record_lyric (voice_context_id, h);
-    return;
-  }
 
   /* Catch any extender items and then if we have a melisma, 
      set the RIGHT item of the extender spanner to the melismatic note in 
@@ -225,23 +235,26 @@ Lyric_phrasing_engraver::acknowledge_grob (Grob_info i)
      then ignore it and let the Extender_engraver take care of it (i.e. finish at next
      lyric).
   */
-  if (h->internal_has_interface (ly_symbol2scm ("lyric-extender-interface"))) {
-    String voice_context_id = get_context_id (i.origin_trans_l_->daddy_trans_l_, "LyricsVoice");
-    record_extender (trim_suffix (voice_context_id), h);
-    return;
-  }
+  if (h->internal_has_interface (ly_symbol2scm ("lyric-extender-interface")))
+    {
+      String voice_context_id = get_context_id (i.origin_trans_l_->daddy_trans_l_, "LyricsVoice");
+      record_extender (trim_suffix (voice_context_id), h);
+      return;
+    }
 }
 
 String 
 get_context_id (Translator_group * ancestor, const char *type)
 {
-  while (ancestor != 0 && ancestor->type_str_ != type) {
-    ancestor = ancestor->daddy_trans_l_;
-  }
+  while (ancestor != 0 && ancestor->type_str_ != type)
+    {
+      ancestor = ancestor->daddy_trans_l_;
+    }
 
-  if (ancestor != 0) {
-    return ancestor->id_str_;
-  }
+  if (ancestor != 0)
+    {
+      return ancestor->id_str_;
+    }
 
   return "";
 }
@@ -250,15 +263,22 @@ String
 trim_suffix (String &id)
 {
   int index = id.index_i ('-');
-  if (index >= 0) {
-    return id.left_str (index);
-  }
+  if (index >= 0)
+    {
+      return id.left_str (index);
+    }
   return id;
 }
 
 
-void Lyric_phrasing_engraver::create_grobs () 
+void
+Lyric_phrasing_engraver::create_grobs () 
 {
+  SCM p = get_property ("automaticPhrasing");
+  if (!to_boolean (p))
+    return;
+
+  
   /* iterate through entries in voice_alist_
      for each, call set_lyric_align (alignment). Issue a warning if this returns false.
   */
@@ -266,60 +286,66 @@ void Lyric_phrasing_engraver::create_grobs ()
   SCM sp = get_property ("phrasingPunctuation");
   punc = gh_string_p (sp) ? ly_scm2string (sp) : ".,;:?!\""; 
   
-  for (SCM v=voice_alist_; gh_pair_p (v); v = ly_cdr (v)) {
-    SCM v_entry = ly_cdar (v);
-    // ((current . oldflag) . previous)
-    if (!to_boolean (ly_cdar (v_entry))) { // not an old entry left over from a prior note ...
-      Syllable_group *entry = unsmob_voice_entry (ly_caar (v_entry));
-
-      /*
-       TODO: give context for warning.
-       */
-      if (! entry->set_lyric_align (punc.ch_C (), any_notehead_l_))
-       warning (_ ("lyrics found without any matching notehead"));
-
-      // is this note melismatic? If so adjust alignment of previous one.
-      if (entry->get_melisma ()) {
-       if (entry->lyric_count ())
-         warning (_ ("Huh? Melismatic note found to have associated lyrics."));
-       SCM previous_scm = ly_cdr (v_entry);
-       if (previous_scm != SCM_EOL) {
-         Syllable_group *previous = unsmob_voice_entry (previous_scm);
-         if (previous->lyric_count ())
-           previous->adjust_melisma_align ();
+  for (SCM v=voice_alist_; gh_pair_p (v); v = ly_cdr (v))
+    {
+      SCM v_entry = ly_cdar (v);
+      // ((current . oldflag) . previous)
+      if (!to_boolean (ly_cdar (v_entry)))
+       { // not an old entry left over from a prior note ...
+         Syllable_group *entry = unsmob_voice_entry (ly_caar (v_entry));
+
+         /*
+           TODO: give context for warning.
+         */
+         if (! entry->set_lyric_align (punc.ch_C (), any_notehead_l_))
+           warning (_ ("lyrics found without any matching notehead"));
+
+         // is this note melismatic? If so adjust alignment of previous one.
+         if (entry->get_melisma ())
+           {
+             if (entry->lyric_count ())
+               warning (_ ("Huh? Melismatic note found to have associated lyrics."));
+             SCM previous_scm = ly_cdr (v_entry);
+             if (previous_scm != SCM_EOL)
+               {
+                 Syllable_group *previous = unsmob_voice_entry (previous_scm);
+                 if (previous->lyric_count ())
+                   previous->adjust_melisma_align ();
+               }
+           }
        }
-      }
     }
-  }
 }
 
 
 void
 Lyric_phrasing_engraver::stop_translation_timestep ()
 {
-  for (SCM v=voice_alist_; gh_pair_p (v); v = ly_cdr (v)) {
-    SCM entry_scm = ly_cdar (v);
-    // ((alist_entry . entry_is_old) . previous_entry)
-    Syllable_group * entry = unsmob_voice_entry (ly_caar (entry_scm));
-
-    // set previous_entry, set entry_is_old, and resave it to alist_
-    // but only change if this current was not old.
-    if (! to_boolean (ly_cdar (entry_scm))) { 
-      Syllable_group * previous_entry = unsmob_voice_entry (ly_cdr (entry_scm));
-      previous_entry->copy (entry);
-      entry_scm = gh_cons (gh_cons (ly_caar (entry_scm), SCM_BOOL_T), ly_cdr (entry_scm));
-      voice_alist_ = scm_assoc_set_x (voice_alist_, ly_caar (v), entry_scm);
+  for (SCM v=voice_alist_; gh_pair_p (v); v = ly_cdr (v))
+    {
+      SCM entry_scm = ly_cdar (v);
+      // ((alist_entry . entry_is_old) . previous_entry)
+      Syllable_group * entry = unsmob_voice_entry (ly_caar (entry_scm));
+
+      // set previous_entry, set entry_is_old, and resave it to alist_
+      // but only change if this current was not old.
+      if (! to_boolean (ly_cdar (entry_scm)))
+       { 
+         Syllable_group * previous_entry = unsmob_voice_entry (ly_cdr (entry_scm));
+         previous_entry->copy (entry);
+         entry_scm = gh_cons (gh_cons (ly_caar (entry_scm), SCM_BOOL_T), ly_cdr (entry_scm));
+         voice_alist_ = scm_assoc_set_x (voice_alist_, ly_caar (v), entry_scm);
+       }
+      entry->next_lyric ();
     }
-    entry->next_lyric ();
-  }
   any_notehead_l_ = 0;
 }
 
 
 
 ENTER_DESCRIPTION(Lyric_phrasing_engraver,
-/* descr */       "",
-/* creats*/       "",
-/* acks  */       "lyric-syllable-interface note-head-interface lyric-extender-interface",
-/* reads */       "automaticPhrasing melismaEngraverBusy associatedVoice phrasingPunctuation",
-/* write */       "");
+                 /* descr */       "",
+                 /* creats*/       "",
+                 /* acks  */       "lyric-syllable-interface note-head-interface lyric-extender-interface",
+                 /* reads */       "automaticPhrasing melismaEngraverBusy associatedVoice phrasingPunctuation",
+                 /* write */       "");