]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/musicxml2ly.py
Add grace defaults for Fingering/StringNumber.
[lilypond.git] / scripts / musicxml2ly.py
index 5a8896c1b0b297b0594803cbe2d7aae83c099426..d9dfaf3be64171ae4de27938ac1f56be4b22434c 100644 (file)
@@ -273,15 +273,15 @@ def extract_score_information (tree):
         if value:
             header.set_field (field, musicxml.escape_ly_output_string (value))
 
+    movement_title = tree.get_maybe_exist_named_child ('movement-title')
+    if movement_title:
+        set_if_exists ('title', movement_title.get_text ())
     work = tree.get_maybe_exist_named_child ('work')
     if work:
+        # Overwrite the title from movement-title with work->title
         set_if_exists ('title', work.get_work_title ())
         set_if_exists ('worknumber', work.get_work_number ())
         set_if_exists ('opus', work.get_opus ())
-    else:
-        movement_title = tree.get_maybe_exist_named_child ('movement-title')
-        if movement_title:
-            set_if_exists ('title', movement_title.get_text ())
     
     identifications = tree.get_named_children ('identification')
     for ids in identifications:
@@ -308,6 +308,7 @@ def extract_score_information (tree):
         # Case 1: "Sibelius 5.1" with the "Dolet 3.4 for Sibelius" plugin
         #         is missing all beam ends => ignore all beaming information
         ignore_beaming_software = {
+            "Dolet 4 for Sibelius, Beta 2": "Dolet 4 for Sibelius, Beta 2",
             "Dolet 3.5 for Sibelius": "Dolet 3.5 for Sibelius",
             "Dolet 3.4 for Sibelius": "Dolet 3.4 for Sibelius",
             "Dolet 3.3 for Sibelius": "Dolet 3.3 for Sibelius",
@@ -930,6 +931,30 @@ def musicxml_attributes_to_lily (attrs):
                 elts.append (ev)
     
     return elts
+    
+def musicxml_print_to_lily (el):
+    # TODO: Implement other print attributes
+    #  <!ELEMENT print (page-layout?, system-layout?, staff-layout*,
+    #          measure-layout?, measure-numbering?, part-name-display?, 
+    #          part-abbreviation-display?)>
+    #  <!ATTLIST print
+    #      staff-spacing %tenths; #IMPLIED
+    #      new-system %yes-no; #IMPLIED
+    #      new-page %yes-no-number; #IMPLIED
+    #      blank-page NMTOKEN #IMPLIED
+    #      page-number CDATA #IMPLIED 
+    #  >
+    elts = []
+    if (hasattr (el, "new-system")):
+        val = getattr (el, "new-system")
+        if (val == "yes"):
+            elts.append (musicexp.Break ("break"))
+    if (hasattr (el, "new-page")):
+        val = getattr (el, "new-page")
+        if (val == "yes"):
+            elts.append (musicexp.Break ("pageBreak"))
+    return elts
+
 
 class Marker (musicexp.Music):
     def __init__ (self):
@@ -2083,6 +2108,7 @@ def musicxml_voice_to_lily_voice (voice):
     voice_builder.set_measure_length (current_measure_length)
 
     for n in voice._elements:
+        tie_started = False
         if n.get_name () == 'forward':
             continue
         staff = n.get_maybe_exist_named_child ('staff')
@@ -2126,6 +2152,12 @@ def musicxml_voice_to_lily_voice (voice):
                     chordnames_builder.add_barline (a, False)
             continue
 
+
+        if isinstance (n, musicxml.Print):
+            for a in musicxml_print_to_lily (n):
+                voice_builder.add_command (a, False)
+            continue
+
         # Continue any multimeasure-rests before trying to add bar checks!
         # Don't handle new MM rests yet, because for them we want bar checks!
         rest = n.get_maybe_exist_typed_child (musicxml.Rest)
@@ -2319,6 +2351,7 @@ def musicxml_voice_to_lily_voice (voice):
                 if mxl_tie and mxl_tie.type == 'start':
                     ev_chord.append (musicexp.TieEvent ())
                     is_tied = True
+                    tie_started = True
                 else:
                     is_tied = False
 
@@ -2414,7 +2447,13 @@ def musicxml_voice_to_lily_voice (voice):
                 if not lnr in note_lyrics_processed:
                     lyrics[lnr].append ("\skip4")
 
-    ## force trailing mm rests to be written out.   
+        # Assume that a <tie> element only lasts for one note.
+        # This might not be correct MusicXML interpretation, but works for
+        # most cases and fixes broken files, which have the end tag missing
+        if is_tied and not tie_started:
+            is_tied = False
+
+    ## force trailing mm rests to be written out.
     voice_builder.add_music (musicexp.ChordEvent (), Rational (0))
     
     ly_voice = group_tuplets (voice_builder.elements, tuplet_events)
@@ -2520,7 +2559,17 @@ def voices_in_part (part):
 
 def voices_in_part_in_parts (parts):
     """return a Part -> Name -> Voice dictionary"""
-    return dict([(p.id, voices_in_part (p)) for p in parts])
+    # don't crash if p doesn't have an id (that's invalid MusicXML,
+    # but such files are out in the wild!
+    dictionary = {}
+    for p in parts:
+        voices = voices_in_part (p)
+        if (hasattr (p, "id")):
+             dictionary[p.id] = voices
+        else:
+             # TODO: extract correct part id from other sources
+             dictionary[None] = voices
+    return dictionary;
 
 
 def get_all_voices (parts):