]> git.donarmstrong.com Git - lilypond.git/commitdiff
MusicXML: Implement elisions (multiple lyrics syllables assigned to one note)
authorReinhold Kainhofer <reinhold@kainhofer.com>
Sat, 29 Nov 2008 19:20:33 +0000 (20:20 +0100)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Sat, 29 Nov 2008 19:20:33 +0000 (20:20 +0100)
input/regression/musicxml/06j-Lyrics-Elisions.xml [new file with mode: 0644]
python/musicxml.py
scripts/musicxml2ly.py

diff --git a/input/regression/musicxml/06j-Lyrics-Elisions.xml b/input/regression/musicxml/06j-Lyrics-Elisions.xml
new file mode 100644 (file)
index 0000000..f525d10
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise version="1.1">\r
+  <identification>\r
+    <miscellaneous>\r
+      <miscellaneous-field name="description">Multiple lyrics syllables \r
+          assigned to a single note are implemented either using a space in \r
+          the lyrics or by using the &lt;elision&gt; lyrics element. This \r
+          testcase checks both of them. First, a note with on syllable is\r
+          given, then a note with two syllables separated by a spcae and finally\r
+          a note with two and one with three syllables implemented using \r
+          &lt;elision&gt; is given.</miscellaneous-field>\r
+    </miscellaneous>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>1</duration>\r
+        <voice>1</voice>\r
+        <type>quarter</type>\r
+        <stem>down</stem>\r
+        <lyric number="1">\r
+          <text>a</text>\r
+        </lyric>\r
+      </note>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>1</duration>\r
+        <voice>1</voice>\r
+        <type>quarter</type>\r
+        <stem>down</stem>\r
+        <lyric number="1">\r
+          <text>b c</text>\r
+        </lyric>\r
+      </note>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>1</duration>\r
+        <voice>1</voice>\r
+        <type>quarter</type>\r
+        <stem>down</stem>\r
+        <lyric number="1">\r
+          <text>d</text>\r
+          <elision/>\r
+          <text>e</text>\r
+        </lyric>\r
+      </note>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>1</duration>\r
+        <voice>1</voice>\r
+        <type>quarter</type>\r
+        <stem>down</stem>\r
+        <lyric number="1">\r
+          <text>f</text>\r
+          <elision/>\r
+          <text>g</text>\r
+          <elision/>\r
+          <text>h</text>\r
+        </lyric>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
index 0c062648129914461a0cfbaa7a640573bd81129f..1c159924b0ab6d6a7905fa9118dc76a2132b26c3 100644 (file)
@@ -462,6 +462,8 @@ class Syllabic (Music_xml_node):
     def continued (self):
         text = self.get_text()
         return (text == "begin") or (text == "middle")
+class Elision (Music_xml_node):
+    pass
 class Text (Music_xml_node):
     pass
 
@@ -472,32 +474,6 @@ class Lyric (Music_xml_node):
         else:
             return -1
 
-    def lyric_to_text (self):
-        continued = False
-        syllabic = self.get_maybe_exist_typed_child (Syllabic)
-        if syllabic:
-            continued = syllabic.continued ()
-        text = self.get_maybe_exist_typed_child (Text)
-        
-        if text:
-            text = text.get_text()
-            # We need to convert soft hyphens to -, otherwise the ascii codec as well
-            # as lilypond will barf on that character
-            text = string.replace( text, u'\xad', '-' )
-        
-        if text == "-" and continued:
-            return "--"
-        elif text == "_" and continued:
-            return "__"
-        elif continued and text:
-            return escape_ly_output_string (text) + " --"
-        elif continued:
-            return "--"
-        elif text:
-            return escape_ly_output_string (text)
-        else:
-            return ""
-
 class Musicxml_voice:
     def __init__ (self):
        self._elements = []
@@ -1122,6 +1098,7 @@ class_dict = {
        'direction': Direction,
         'direction-type': DirType,
        'duration': Duration,
+        'elision': Elision,
         'frame': Frame,
         'frame-note': Frame_Note,
         'figured-bass': FiguredBass,
index f29fa3ecbc772d178782a7dc6698f80232ab7a70..c4926da8ac25174cccabad5ecd2145da15e1213c 100644 (file)
@@ -1732,6 +1732,34 @@ def musicxml_note_to_lily_main_event (n):
 
     return event
 
+def musicxml_lyrics_to_text (lyrics):
+    # TODO: Implement text styles for lyrics syllables
+    continued = False
+    text = ''
+    for e in lyrics.get_all_children ():
+        if isinstance (e, musicxml.Syllabic):
+            continued = e.continued ()
+        elif isinstance (e, musicxml.Text):
+            # We need to convert soft hyphens to -, otherwise the ascii codec as well
+            # as lilypond will barf on that character
+            text += string.replace( e.get_text(), u'\xad', '-' )
+        elif isinstance (e, musicxml.Elision):
+            if text:
+                text += " "
+            continued = False
+
+    if text == "-" and continued:
+        return "--"
+    elif text == "_" and continued:
+        return "__"
+    elif continued and text:
+        return musicxml.escape_ly_output_string (text) + " --"
+    elif continued:
+        return "--"
+    elif text:
+        return musicxml.escape_ly_output_string (text)
+    else:
+        return ""
 
 ## TODO
 class NegativeSkip:
@@ -2255,10 +2283,10 @@ def musicxml_voice_to_lily_voice (voice):
             for l in note_lyrics_elements:
                 if l.get_number () < 0:
                     for k in lyrics.keys ():
-                        lyrics[k].append (l.lyric_to_text ())
+                        lyrics[k].append (musicxml_lyrics_to_text (l))
                         note_lyrics_processed.append (k)
                 else:
-                    lyrics[l.number].append(l.lyric_to_text ())
+                    lyrics[l.number].append(musicxml_lyrics_to_text (l))
                     note_lyrics_processed.append (l.number)
             for lnr in lyrics.keys ():
                 if not lnr in note_lyrics_processed: