# -*- coding: ISO-8859-1 -*- """ capellaScript -- Copyright (c) 2003 Peter Becker >>> BindebogenFix : Bindebogen Korrektur nach Zeilentrennung Nach der Trennung von überbundenen Takten verschwindet der Bindebogen in der Folgezeile. Dieses Script zieht den getrennten Bindebogen bis ans Zeilenende und setzt einen neuen Bindebogen bis zur entsprechenden Zielnote in die Folgezeile. | | Achtung : Die Form der Bindebogen muss derzeit noch von Hand optimiert werden ! | | Bei Problemen bitte eine Mail an peter_becker@freenet.de <<< History: 26.01.04 - Erste Ausgabe 17.04.04 - y-setting für die Folgezeile entfernt, damit Bögen in der korrekten Stimme landen 31.03.07 - Absturz bei unvollständigen Zeilen verhindert 18.12.08 - nur noch den Bindebogen an die Folgezeile hängen """ from xml.dom.minidom import NodeList def getElementObjects(objList): # returns a List, diese Unterroutine habe ich bei newList = NodeList() # Paul Villiger 'liberalisiert'. Danke Paul. for n in range(objList.length): if objList[n].nodeType == objList[n].ELEMENT_NODE: newList.append(objList[n]) return newList def addElementNode(el,tagName,score): # Neue Node zu "el" hinzufügen wenn Node "tagName" nicht existiert # ansonsten existierende Node zurückmelden global doc childs = el.childNodes for n in range(childs.length): if childs[n].nodeType ==childs[n].ELEMENT_NODE and childs[n].tagName == tagName: return childs[n] newChild = score.parentNode.createElement(tagName) el.appendChild(newChild) return newChild def findLimits(sy,st,vo): system = activeScore().system(sy) staff = system.staff(st) voice = staff.voice(vo) anzahl = voice.nNoteObjs() if anzahl > 2: n = anzahl - 2 else: n = anzahl x2 = 0 x3 = 0 valid = 0 while n < anzahl: obj = voice.noteObj(n) x3 = obj.posX() + 4 # Zeilenende wenn kein Taktstrich if obj.subType() == NoteObj.CHORD or obj.subType() == NoteObj.REST: x2 = obj.posX() # Position letzte Note/Pause valid = 1 if obj.implBarline()!= 0: x3 = obj.implBarline().posX() # normales Zeilenende elif obj.subType() == NoteObj.EXPL_BARLINE: x3 = obj.posX() # Zeilenende mit explizitem Taktstrich n = n +1 return(x2,x3,valid) def findOpenSlur(sy,st,vo,ob,slurRange): system = activeScore().system(sy) staff = system.staff(st) voice = staff.voice(vo) anzahl = voice.nNoteObjs() slurRangeRest = slurRange # Bindebogen analysieren n = ob anzahl = voice.nNoteObjs() posObjEnd = 0 while n < voice.nNoteObjs(): obj = voice.noteObj(n) if obj.subType() == NoteObj.CHORD: prevPos = posObjEnd posObjEnd = obj.posX() elif obj.subType() == NoteObj.REST: prevPos = posObjEnd posObjEnd = obj.posX() if n == ob: startPos = posObjEnd n = n + 1 slurRangeRest = slurRangeRest - 1 if slurRangeRest < 0: slurFound = 'notTrue' slurRest = -1 else: slurFound = 'True' slurRest = slurRangeRest x1 = startPos return (x1,slurFound,slurRest) def changeDoc(score): systems = score.getElementsByTagName('system') for sy in range(systems.length): staves = systems[sy].getElementsByTagName('staff') for st in range(staves.length): voices = staves[st].getElementsByTagName('voice') for vo in range(voices.length): noteObjects = getElementObjects(voices[vo].getElementsByTagName('noteObjects')[0].childNodes) lastNote,lineEnd,valid = findLimits(sy,st,vo) # letzte Note und Zeilenende feststellen if valid == 0: continue for ob in range(noteObjects.length): # Anzahl Note Objects in der Zeile slurs = noteObjects[ob].getElementsByTagName('slur') if slurs: for slur in slurs: for basic in slur.parentNode.getElementsByTagName('basic'): slurRange = eval(basic.getAttribute('noteRange')) x1,slurFound,slurRest = findOpenSlur(sy, st, vo, ob, slurRange) if slurFound == 'True': deltaSlur = lineEnd-lastNote # Bindebogen auf Zeilenende begrenzen slur.setAttribute('x4',str(deltaSlur)) slur.setAttribute('x3',str(deltaSlur-1)) slur.setAttribute('x1','1.35') slur.setAttribute('x2','2.35') slurObj = slur.parentNode.parentNode.parentNode.getElementsByTagName('drawObjects') # Problem. hier werden alle drawObjs mitgenommen drawObjClone = slurObj[0].cloneNode('TRUE') slurObjClone = slurObj[0].cloneNode('TRUE') NdrawObjects = drawObjClone.getElementsByTagName('drawObj') for dos in range(NdrawObjects.length): slur = NdrawObjects[dos].getElementsByTagName('slur') if slur: slurObjClone = slur[0].parentNode break # erste Note der Folgezeile lokalisieren nstaves = systems[sy+1].getElementsByTagName('staff') nvoices = nstaves[st].getElementsByTagName('voice') NnoteObjects = getElementObjects(nvoices[vo].getElementsByTagName('noteObjects')[0].childNodes) Nob = 0 # und korrigierten Bindebogen anhängen for Nob in range(NnoteObjects.length): Nchords = NnoteObjects[Nob].parentNode.getElementsByTagName('chord') dOs = addElementNode(Nchords[0],'drawObjects',score) dOs.appendChild(slurObjClone) NdrawObj = NnoteObjects[Nob].parentNode.getElementsByTagName('drawObj') Nbasic = NnoteObjects[Nob].parentNode.getElementsByTagName('basic') Nbasic[0].setAttribute('noteRange',str(slurRest)) Nslur = NnoteObjects[Nob].parentNode.getElementsByTagName('slur') Nbasic[0].setAttribute('tag','2086-1') # neuen Bindebogen markieren Nslur[0].setAttribute('x1','-2.6') #Nslur[0].setAttribute('y1','3') # y setting entfernt, damit Nslur[0].setAttribute('x2','-2') # die Bögen in der korrekten #Nslur[0].setAttribute('y2','5,78') # Stimme landen Nslur[0].setAttribute('x4','0') #Nslur[0].setAttribute('y4','3') Nslur[0].setAttribute('x3','-2') #Nslur[0].setAttribute('y3','5,78') break # Hauptprogramm: from caplib.capDOM import ScoreChange import tempfile class ScoreChange(ScoreChange): def changeScore(self, score): changeDoc(score) if activeScore(): activeScore().registerUndo("BindebogenFix") activeScore().deleteTaggedGraphics('2086-1') # eventuell vorhandene, durch dieses Script erzeugte, tempInput = tempfile.mktemp('.capx') # Bindebögen entfernen tempOutput = tempfile.mktemp('.capx') activeScore().write(tempInput) ScoreChange(tempInput, tempOutput) activeScore().read(tempOutput) os.remove(tempInput) os.remove(tempOutput)