]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 3815: Parser: harmonize \lyricsto and \addlyrics arguments
authorDavid Kastrup <dak@gnu.org>
Thu, 16 Jan 2014 10:25:23 +0000 (11:25 +0100)
committerDavid Kastrup <dak@gnu.org>
Tue, 21 Jan 2014 12:24:11 +0000 (13:24 +0100)
Previously, they allowed arbitrary music but since that required looking
at lookahead tokens in the wrong mode, it led to strange errors like with
lyr=\lyricsto A { }
mus={c}
when mus= was parsed as a single token in lyrics mode.  Now both \addlyrics
and \lyricsto accept merely the same kind of delimited argument list
that \lyrics or \chords accept.  Additionally, to preserve compatibility
to a lot of examples, music identifiers like \mus are permitted as the
argument to \lyricsto and \addlyrics.

Since this requires a change in existing uses, this includes a
convert-ly rule that removes redundant uses of \lyricmode and
rearranges the combination with context starters such that \lyricsto
in general is applied last, like \lyricmode would be.

lily/parser.yy
python/convertrules.py

index 2a647c1ec6a2b328d9935dea430652b0933ae2ce..ccc87218f2e64b517a5fb3600608beb93e147357 100644 (file)
@@ -2058,6 +2058,23 @@ optional_id:
        }
        ;
 
+// We must not have lookahead tokens parsed in lyric mode.  In order
+// to save confusion, we take almost the same set as permitted with
+// \lyricmode and/or \lyrics.  However, music identifiers are also
+// allowed, and they obviously do not require switching into lyrics
+// mode for parsing.
+
+lyric_mode_music:
+       {
+               parser->lexer_->push_lyric_state ();
+       } grouped_music_list
+       {
+               parser->lexer_->pop_state ();
+               $$ = $2;
+       }
+       | MUSIC_IDENTIFIER
+       ;
+
 complex_music:
        music_function_call
        | repeated_music                { $$ = $1; }
@@ -2170,20 +2187,11 @@ mode_changing_head_with_context:
        ;
 
 new_lyrics:
-       ADDLYRICS { parser->lexer_->push_lyric_state (); }
-       /*cont */
-       composite_music {
-       /* Can also use music at the expensive of two S/Rs similar to
-           \repeat \alternative */
-               parser->lexer_->pop_state ();
-
-               $$ = scm_cons ($3, SCM_EOL);
+       ADDLYRICS lyric_mode_music {
+               $$ = scm_list_1 ($2);
        }
-       | new_lyrics ADDLYRICS {
-               parser->lexer_->push_lyric_state ();
-       } composite_music {
-               parser->lexer_->pop_state ();
-               $$ = scm_cons ($4, $1);
+       | new_lyrics ADDLYRICS lyric_mode_music {
+               $$ = scm_cons ($3, $1);
        }
        ;
 
@@ -2191,11 +2199,8 @@ re_rhythmed_music:
        composite_music new_lyrics {
                $$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL));
        } %prec COMPOSITE
-       | LYRICSTO simple_string {
-               parser->lexer_->push_lyric_state ();
-       } music {
-               parser->lexer_->pop_state ();
-               $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $4);
+       | LYRICSTO simple_string lyric_mode_music {
+               $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $3);
        }
        ;
 
index ec8bd266ef7cfc2c2307d430548cb271e09de037..bbafef4a3da5146da99d26cc48a3796c1f7f4f33 100644 (file)
@@ -3698,6 +3698,19 @@ def conv (str):
 def conv (str):
     return str
 
+@rule ((2, 19, 2), r"\lyricsto \new/\context/... -> \new/\context/... \lyricsto")
+def conv (str):
+    word=r'(?:#?"[^"]*"|\b' + wordsyntax + r'\b)'
+    str = re.sub (r"(\\lyricsto\s*" + word + r"\s*)(\\(?:new|context)\s*" + word
+                  + r"(?:\s*=\s*" + word + r")?\s*)",
+                  r"\2\1", str)
+    str = re.sub (r"(\\lyricsto\s*" + word + r"\s*)\\lyricmode\b\s*",
+                  r"\1", str)
+    str = re.sub (r"(\\lyricsto\s*" + word + r"\s*)\\lyrics\b\s*",
+                  r"\\new Lyrics \1", str)
+    str = re.sub (r'\\lyricmode\s*(\\lyricsto\b)', r"\1", str)
+    return str
+
 # Guidelines to write rules (please keep this at the end of this file)
 #
 # - keep at most one rule per version; if several conversions should be done,