encodage des caractères : minwii semble être content avec du iso-8859-1
[minwii.git] / src / songs / musicxmltosong.py
index 068017f..d24d81a 100755 (executable)
@@ -41,6 +41,7 @@ class Part(object) :
     def __init__(self, node, autoDetectChorus=True) :
         self.node = node
         self.notes = []
+        self.repeats = []
         self._parseMusic()
         self.verses = [[]]
         self.chorus = []
@@ -54,6 +55,8 @@ class Part(object) :
 
         for measureNode in self.node.getElementsByTagName('measure') :
             measureNotes = []
+            
+            # iteration sur les notes
             # divisions de la noire
             divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions))
             for noteNode in measureNode.getElementsByTagName('note') :
@@ -66,8 +69,17 @@ class Part(object) :
                     previous.addDuration(note)
                     continue
                 previous = note
-
             self.notes.extend(measureNotes)
+            
+            # barres de reprises
+            try :
+                barlineNode = measureNode.getElementsByTagName('barline')[0]
+            except IndexError :
+                continue
+            
+            barline = Barline(barlineNode, measureNotes)
+            if barline.repeat :
+                self.repeats.append(barline)
 
     def _findChorus(self):
         """ le refrain correspond aux notes pour lesquelles
@@ -98,7 +110,7 @@ class Part(object) :
     
     def iterNotes(self) :
         "exécution de la chanson avec l'alternance couplets / refrains"
-        for verse in self.verses :
+        for verse in cycle(self.verses) :
             print "---partie---"
             repeats = len(verse[0].lyrics)
             if repeats > 1 :
@@ -133,17 +145,32 @@ class Part(object) :
 
 class Barline(object) :
 
-    def __init__(self, node) :
+    def __init__(self, node, measureNotes) :
         self.node = node
-        self.location = node.getAttribute('location')
+        location = self.location = node.getAttribute('location') or 'right'
         try :
-            repeat = node.getElementsByTagName('repeat')[0]
-            repeat = {'direction' : repeat.getAttribute('direction'),
-                      'times' : int(repeat.getAttribute('times') or 1)}
+            repeatN = node.getElementsByTagName('repeat')[0]
+            repeat = {'direction' : repeatN.getAttribute('direction'),
+                      'times' : int(repeatN.getAttribute('times') or 1)}
+            if location == 'left' :
+                repeat['note'] = measureNotes[0]
+            elif location == 'right' :
+                repeat['note'] = measureNotes[-1]
+            else :
+                raise ValueError(location)
             self.repeat = repeat
         except IndexError :
             self.repeat = None
-        
+    
+    def __str__(self)  :
+        if self.repeat :
+            if self.location == 'left' :
+                return '|:'
+            elif self.location == 'right' :
+                return ':|'
+        return '|'
+
+    __repr__ = __str__
         
 
 class Note(object) :
@@ -173,7 +200,8 @@ class Note(object) :
     def __str__(self) :
         return (u'%5s %2s %2d %4s' % (self.nom, self.name, self.midi, round(self.duration, 2))).encode('utf-8')
     
-    __repr__ = __str__
+    def __repr__(self) :
+        return self.name.encode('utf-8')
     
     def addDuration(self, note) :
         self._duration = self.duration + note.duration
@@ -229,9 +257,12 @@ class Lyric(object) :
         self.syllabic = _getNodeValue(node, 'syllabic', 'single')
         self.text = _getNodeValue(node, 'text')
     
-    def __str__(self) :
+    def syllabus(self, encoding='utf-8'):
         text = self._syllabicModifiers[self.syllabic] % self.text
-        return text.encode('utf-8')
+        return text.encode(encoding)
+    
+    def __str__(self) :
+        return self.syllabus()
     __repr__  = __str__