]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/musicxml.py
MusicXML: convert score information into the \header{..} construct in lilypond.
[lilypond.git] / python / musicxml.py
index 132ce5a752021d2798d60f0c86425873cb37b628..2056805aeee13accd26da2173f1404c5019b18b5 100644 (file)
@@ -57,7 +57,7 @@ class Xml_node:
        return self._children
 
     def get_maybe_exist_named_child (self, name):
-       return self.get_maybe_exist_typed_child (class_dict[name])
+       return self.get_maybe_exist_typed_child (class_dict.get (name))
 
     def get_maybe_exist_typed_child (self, klass):
        cn = self.get_typed_children (klass)
@@ -82,6 +82,74 @@ class Music_xml_node (Xml_node):
        self.duration = Rational (0)
        self.start = Rational (0)
 
+class Work (Xml_node):
+    def get_work_information (self, tag):
+        wt = self.get_maybe_exist_named_child (tag)
+        if wt:
+            return wt.get_text ()
+        else:
+            return self.get_text ()
+      
+    def get_work_title (self):
+        return self.get_work_information ('work-title')
+    def get_work_number (self):
+        return self.get_work_information ('work-number')
+    def get_opus (self):
+        return self.get_work_information ('opus')
+
+class Identification (Xml_node):
+    def get_rights (self):
+        rights = self.get_maybe_exist_named_child ('rights')
+        if rights:
+            return rights.get_text ()
+        else:
+            return ''
+
+    def get_creator (self, type):
+        creators = self.get_named_children ('creator')
+        # return the first creator tag that has type 'editor'
+        for i in creators:
+            if hasattr (i, 'type') and i.type == type:
+                return i.get_text ()
+            else:
+                return ''
+
+    def get_composer (self):
+        c = self.get_creator ('composer')
+        if c:
+            return c
+        creators = self.get_named_children ('creator')
+        # return the first creator tag that has no type at all
+        for i in creators:
+            if not hasattr (i, 'type'):
+                return i.get_text ()
+        return c
+    def get_arranger (self):
+        return self.get_creator ('arranger')
+    def get_editor (self):
+        return self.get_creator ('editor')
+    def get_poet (self):
+        return self.get_creator ('poet')
+    
+    def get_encoding_information (self, type):
+        enc = self.get_named_children ('encoding')
+        if enc:
+            children = enc[0].get_named_children (type)
+            if children:
+                return children[0].get_text ()
+        else:
+            return ''
+      
+    def get_encoding_software (self):
+        return self.get_encoding_information ('software')
+    def get_encoding_date (self):
+        return self.get_encoding_information ('encoding-date')
+    def get_encoding_person (self):
+        return self.get_encoding_information ('encoder')
+    def get_encoding_description (self):
+        return self.get_encoding_information ('encoding-description')
+      
+
 
 class Duration (Music_xml_node):
     def get_length (self):
@@ -93,17 +161,17 @@ class Hash_comment (Music_xml_node):
 
 class Pitch (Music_xml_node):
     def get_step (self):
-       ch = self.get_unique_typed_child (class_dict[u'step'])
+       ch = self.get_unique_typed_child (class_dict.get (u'step'))
        step = ch.get_text ().strip ()
        return step
     def get_octave (self):
-       ch = self.get_unique_typed_child (class_dict[u'octave'])
+       ch = self.get_unique_typed_child (class_dict.get (u'octave'))
 
        step = ch.get_text ().strip ()
        return int (step)
 
     def get_alteration (self):
-       ch = self.get_maybe_exist_typed_child (class_dict[u'alter'])
+       ch = self.get_maybe_exist_typed_child (class_dict.get (u'alter'))
        alter = 0
        if ch:
            alter = int (ch.get_text ().strip ())
@@ -135,7 +203,7 @@ class Attributes (Measure_element):
            self._dict[c.get_name()] = c
 
     def get_named_attribute (self, name):
-       return self._dict[name]
+       return self._dict.get (name)
 
     def get_measure_length (self):
         (n,d) = self.get_time_signature ()
@@ -183,7 +251,7 @@ class Note (Measure_element):
         self.instrument_name = ''
         
     def get_duration_log (self):
-       ch = self.get_maybe_exist_typed_child (class_dict[u'type'])
+       ch = self.get_maybe_exist_typed_child (class_dict.get (u'type'))
 
        if ch:
            log = ch.get_text ().strip()
@@ -194,7 +262,7 @@ class Note (Measure_element):
                     '32nd': 5,
                     'breve': -1,
                     'long': -2,
-                    'whole': 0} [log]
+                    'whole': 0}.get (log)
        else:
            return 0
 
@@ -202,7 +270,7 @@ class Note (Measure_element):
        return 1
 
     def get_pitches (self):
-       return self.get_typed_children (class_dict[u'pitch'])
+       return self.get_typed_children (class_dict.get (u'pitch'))
 
 class Part_list (Music_xml_node):
     def __init__ (self):
@@ -225,15 +293,16 @@ class Part_list (Music_xml_node):
         if not self._id_instrument_name_dict:
             self.generate_id_instrument_dict()
 
-        try:
-            return self._id_instrument_name_dict[id]
-        except KeyError:
+        instrument_name = self._id_instrument_name_dict.get (id)
+        if instrument_name:
+            return instrument_name
+        else:
             print "Opps, couldn't find instrument for ID=", id
             return "Grand Piano"
         
 class Measure(Music_xml_node):
     def get_notes (self):
-       return self.get_typed_children (class_dict[u'note'])
+       return self.get_typed_children (class_dict.get (u'note'))
 
     
 class Musicxml_voice:
@@ -294,7 +363,7 @@ class Part (Music_xml_node):
                     attributes_object = n
                     
                    factor = Rational (1,
-                                      int (attributes_dict['divisions'].get_text ()))
+                                      int (attributes_dict.get ('divisions').get_text ()))
 
                 
                if (n.get_maybe_exist_typed_child (Duration)):
@@ -355,7 +424,7 @@ class Part (Music_xml_node):
 
        start_attr = None
        for n in elements:
-           voice_id = n.get_maybe_exist_typed_child (class_dict['voice'])
+           voice_id = n.get_maybe_exist_typed_child (class_dict.get ('voice'))
 
             # TODO: If the first element of a voice is a dynamics entry,
             #       then voice_id is not yet set! Thus it will currently be ignored
@@ -400,8 +469,8 @@ class Notations (Music_xml_node):
 
 class Time_modification(Music_xml_node):
     def get_fraction (self):
-       b = self.get_maybe_exist_typed_child (class_dict['actual-notes'])
-       a = self.get_maybe_exist_typed_child (class_dict['normal-notes'])
+       b = self.get_maybe_exist_typed_child (class_dict.get ('actual-notes'))
+       a = self.get_maybe_exist_typed_child (class_dict.get ('normal-notes'))
        return (int(a.get_text ()), int (b.get_text ()))
 
 class Accidental (Music_xml_node):
@@ -482,6 +551,14 @@ class DirType (Music_xml_node):
 class Wedge (Music_xml_node):
     pass
 
+class Creator (Music_xml_node):
+    pass
+class Rights (Music_xml_node):
+    pass
+class Encoding (Music_xml_node):
+    pass
+class WorkTitle (Music_xml_node):
+    pass
 
 ## need this, not all classes are instantiated
 ## for every input file.
@@ -521,7 +598,15 @@ class_dict = {
         'direction': Direction,
         'direction-type': DirType,
         'dynamics': Dynamics,
-        'wedge': Wedge
+        'wedge': Wedge,
+        
+        'identification': Identification,
+        'creator': Creator,
+        'rights': Rights,
+        'encoding': Encoding,
+        'work': Work,
+        'work-title': WorkTitle
+        
 }
 
 def name2class_name (name):
@@ -532,9 +617,10 @@ def name2class_name (name):
     return str (name)
 
 def get_class (name):
-    try:
-        return class_dict[name]
-    except KeyError:
+    classname = class_dict.get (name)
+    if classname:
+        return classname
+    else:
        class_name = name2class_name (name)
        klass = new.classobj (class_name, (Music_xml_node,) , {})
        class_dict[name] = klass