예제 #1
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Remove a dot ornament to a given element.
        '''

        neumeid = str(self.get_argument("id", ""))

        # Bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        punctum = self.mei.getElementById(neumeid)
        # check that a punctum element was provided
        if punctum.getName() == "neume" and punctum.getAttribute("name").getValue() == "punctum":
            note = punctum.getDescendantsByName("note")
            if len(note):
                dot = note[0].getChildrenByName("dot")
                # if a dot exists
                if len(dot) == 1:
                    note[0].removeChild(dot[0])

            self.update_or_add_zone(punctum, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #2
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Neumify a group of neumes (with provided ids)
        and give it the given neume name. Also update
        bounding box information.
        '''

        nids = str(self.get_argument("nids", "")).split(",")
        neume_name = str(self.get_argument("name", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        neume = self.create_new_neume(nids, neume_name)
        self.insert_neume(neume, nids[0])
        self.delete_old_neumes(nids)

        # Bounding box
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))

        if lrx and lry and ulx and uly:
            zone = self.get_new_zone(ulx, uly, lrx, lry)
            self.add_zone(neume, zone)

        XmlExport.write(self.mei, fname)

        result = {"nid": neume.getId()}
        self.write(json.dumps(result))
        self.set_status(200)
예제 #3
0
    def output_mei(self, output_path):
        '''
        Write the generated mei to disk
        '''

        # output mei file
        XmlExport.meiDocumentToFile(self.meidoc, output_path)
예제 #4
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Move the given custos element.
        Also update the bounding box information.
        '''

        custos_id = str(self.get_argument("id", ""))
        pname = self.get_argument("pname", None)
        oct = self.get_argument("oct", None)

        # bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        custos = self.mei.getElementById(custos_id)
        if pname is not None and oct is not None:
            custos.addAttribute("pname", str(pname))
            custos.addAttribute("oct", str(oct))

        self.update_or_add_zone(custos, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #5
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        data = json.loads(self.get_argument("data", ""))

        nid = str(data["id"])
        beforeid = str(data["beforeid"])
        
        # Bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        pitch_info = data["pitchInfo"]

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        neume = self.mei.getElementById(nid)

        if pitch_info is not None:
            self.neume_pitch_shift(neume, pitch_info)

        self.reposition_neume(neume, beforeid)
        self.update_or_add_zone(neume, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #6
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Move a division before the given element. There is no
        element to insert before when there is no subsequent
        staff. In this case, the element is inserted at the end
        of the last system. Also sets the bounding box information
        of the new division placement.
        '''

        division_id = str(self.get_argument("id", ""))
        before_id = str(self.get_argument("beforeid", None))

        # bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        division = self.mei.getElementById(division_id)
        self.update_zone(division, ulx, uly, lrx, lry)
        self.reposition_division(division, before_id)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #7
0
파일: models.py 프로젝트: gburlet/robotaba
    def append_guitar_data(self, tuning, capo):
        '''
        Append meta data about the guitar the transcriber is using
        '''

        mei_path = self.get_abs_path()
        mei_doc = XmlImport.documentFromFile(mei_path)

        staff_def = mei_doc.getElementsByName('staffDef')[0]
        g = Guitar(tuning=str(tuning), capo=capo)
        sounding_pitches = g.strings
        # From the MEI guidelines:
        # "this is given using the written pitch, not the sounding pitch. 
        # For example, the Western 6-string guitar, in standard tuning, sounds an octave below written pitch."
        written_pitches = [s.pname + str(s.oct+1) for s in sounding_pitches]

        staff_def.addAttribute('lines', str(len(sounding_pitches)))
        staff_def.addAttribute('tab.strings', " ".join(written_pitches))

        # Capo could be implicitly encoded by setting the pitches of the open strings
        # but I really don't like this solution. Instructions are lost about how to tune
        # and perform the piece on the guitar.
        # TODO: this attribute doesn't exist in MEI, make a custom build
        if capo > 0:
            staff_def.addAttribute('tab.capo', str(capo))

        XmlExport.meiDocumentToFile(mei_doc, mei_path)
예제 #8
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Move a division before the given element. There is no
        element to insert before when there is no subsequent
        staff. In this case, the element is inserted at the end
        of the last system. Also sets the bounding box information
        of the new division placement.
        '''

        division_id = str(self.get_argument("id", ""))
        before_id = str(self.get_argument("beforeid", None))

        # bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        division = self.mei.getElementById(division_id)
        self.update_zone(division, ulx, uly, lrx, lry)
        self.reposition_division(division, before_id)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #9
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a custos. Also add a bounding box
        for this element.
        '''

        pname = str(self.get_argument("pname", ""))
        oct = str(self.get_argument("oct", ""))
        before_id = str(self.get_argument("beforeid", None))

        # bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        custos = self.create_custos(pname, oct)
        self.insert_custos(custos, before_id)
        self.add_zone(custos, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        result = {"id": custos.getId()}
        self.write(json.dumps(result))

        self.set_status(200)
예제 #10
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a doh or fah clef, with a given bounding box.
        Must also update pitched elements on the staff that
        affected by this clef being inserted.
        '''

        data = json.loads(self.get_argument("data", ""))
        shape = str(data["shape"]).upper()
        line = str(data["line"])
        before_id = str(data["beforeid"])

        # bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        clef = self.create_clef(shape, line)
        self.insert_clef(clef, before_id)
        self.create_zone(ulx, uly, lrx, lry, clef)
        self.update_pitched_elements(data["pitchInfo"])

        XmlExport.write(self.mei, fname)

        result = {"id": clef.getId()}
        self.write(json.dumps(result))

        self.set_status(200)
예제 #11
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Ungroup a neume with the provided ID into puncta.
        Create bounding box information for each punctum.
        '''

        data = json.loads(self.get_argument("data", ""))

        nids = str(data["nids"]).split(",")
        bboxes = data["bbs"]

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        newids = []
        for nid, bb in zip(nids, bboxes):
            newids.append(self.insert_puncta(nid, bb))
            self.delete_old_neume(nid)

        XmlExport.write(self.mei, fname)

        result = {"nids": newids}
        self.write(json.dumps(result))

        self.set_status(200)
예제 #12
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        data = json.loads(self.get_argument("data", ""))

        nid = str(data["id"])
        beforeid = str(data["beforeid"])

        # Bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        pitch_info = data["pitchInfo"]

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        neume = self.mei.getElementById(nid)

        if pitch_info is not None:
            self.neume_pitch_shift(neume, pitch_info)

        self.reposition_neume(neume, beforeid)
        self.update_or_add_zone(neume, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #13
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a custos. Also add a bounding box
        for this element.
        '''

        pname = str(self.get_argument("pname", ""))
        oct = str(self.get_argument("oct", ""))
        before_id = str(self.get_argument("beforeid", None))

        # bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        custos = self.create_custos(pname, oct)
        self.insert_custos(custos, before_id)
        self.add_zone(custos, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        result = {"id": custos.getId()}
        self.write(json.dumps(result))

        self.set_status(200)
예제 #14
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Move the given custos element.
        Also update the bounding box information.
        '''

        custos_id = str(self.get_argument("id", ""))
        pname = self.get_argument("pname", None)
        oct = self.get_argument("oct", None)

        # bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        custos = self.mei.getElementById(custos_id)
        if pname is not None and oct is not None:
            custos.addAttribute("pname", str(pname))
            custos.addAttribute("oct", str(oct))

        self.update_or_add_zone(custos, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #15
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a division before the given element. There is one case
        where there is no element to insert before, when there is no
        subsequent staff. In this case, the element is inserted at the end
        of the last system. Also sets the bounding box information of the new
        punctum.
        '''

        div_type = str(self.get_argument("type", ""))
        beforeid = str(self.get_argument("beforeid", None))

        # bounding box
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        zone = self.create_zone(ulx, uly, lrx, lry)
        division = self.create_new_division(div_type)
        self.add_zone(division, zone)
        self.insert_division(division, beforeid)

        XmlExport.write(self.mei, fname)

        result = {"id": division.getId()}
        self.write(json.dumps(result))
        self.set_status(200)
예제 #16
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a doh or fah clef, with a given bounding box.
        Must also update pitched elements on the staff that
        affected by this clef being inserted.
        '''

        data = json.loads(self.get_argument("data", ""))
        shape = str(data["shape"]).upper()
        line = str(data["line"])
        before_id = str(data["beforeid"])

        # bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        clef = self.create_clef(shape, line)
        self.insert_clef(clef, before_id)
        self.create_zone(ulx, uly, lrx, lry, clef)
        self.update_pitched_elements(data["pitchInfo"])

        XmlExport.write(self.mei, fname)

        result = {"id": clef.getId()}
        self.write(json.dumps(result))

        self.set_status(200)
예제 #17
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Change the shape of a given clef. Must also update
        bounding box data since the glyphs for c and f clefs
        are different. Must also update pitched elements on the
        affected staff to correspond with the new clef shape.
        '''

        data = json.loads(self.get_argument("data", ""))
        clef_id = str(data["id"])

        # bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        clef = self.mei.getElementById(clef_id)

        # update clef shape
        clef.addAttribute("shape", str(data["shape"]).upper())

        self.update_or_add_zone(clef, ulx, uly, lrx, lry)
        self.update_pitched_elements(data["pitchInfo"])

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #18
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Remove a dot ornament to a given element.
        '''

        neumeid = str(self.get_argument("id", ""))

        # Bounding box
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        punctum = self.mei.getElementById(neumeid)
        # check that a punctum element was provided
        if punctum.getName() == "neume" and punctum.getAttribute(
                "name").getValue() == "punctum":
            note = punctum.getDescendantsByName("note")
            if len(note):
                dot = note[0].getChildrenByName("dot")
                # if a dot exists
                if len(dot) == 1:
                    note[0].removeChild(dot[0])

            self.update_or_add_zone(punctum, ulx, uly, lrx, lry)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #19
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Neumify a group of neumes (with provided ids)
        and give it the given neume name. Also update
        bounding box information.
        '''

        nids = str(self.get_argument("nids", "")).split(",")
        neume_name = str(self.get_argument("name", ""))
        
        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        neume = self.create_new_neume(nids, neume_name)
        self.insert_neume(neume, nids[0])
        self.delete_old_neumes(nids)

        # Bounding box
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))

        if lrx and lry and ulx and uly:
            zone = self.get_new_zone(ulx, uly, lrx, lry)
            self.add_zone(neume, zone)

        XmlExport.write(self.mei, fname)

        result = {"nid": neume.getId()}
        self.write(json.dumps(result))
        self.set_status(200)
예제 #20
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Move a clef on a staff (must not change staff).
        Updates the bounding box information of the clef
        and updates the pitch information (pitch name and
        octave) of all pitched elements on the affected staff.
        '''

        data = json.loads(self.get_argument("data", ""))
        clef_id = str(data["id"])

        # bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        clef = self.mei.getElementById(clef_id)

        # update staff line the clef is on
        clef.addAttribute("line", str(data["line"]))

        self.update_or_add_zone(clef, ulx, uly, lrx, lry)
        self.update_pitched_elements(data["pitchInfo"])

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #21
0
파일: meicreate.py 프로젝트: agpar/Rodan
    def output_mei(self, output_path):
        '''
        Write the generated mei to disk
        '''

        # output mei file
        XmlExport.meiDocumentToFile(self.meidoc, output_path)
예제 #22
0
    def append_guitar_data(self, tuning, capo):
        '''
        Append meta data about the guitar the transcriber is using
        '''

        mei_path = self.get_abs_path()
        mei_doc = XmlImport.documentFromFile(mei_path)

        staff_def = mei_doc.getElementsByName('staffDef')[0]
        g = Guitar(tuning=str(tuning), capo=capo)
        sounding_pitches = g.strings
        # From the MEI guidelines:
        # "this is given using the written pitch, not the sounding pitch.
        # For example, the Western 6-string guitar, in standard tuning, sounds an octave below written pitch."
        written_pitches = [s.pname + str(s.oct + 1) for s in sounding_pitches]

        staff_def.addAttribute('lines', str(len(sounding_pitches)))
        staff_def.addAttribute('tab.strings', " ".join(written_pitches))

        # Capo could be implicitly encoded by setting the pitches of the open strings
        # but I really don't like this solution. Instructions are lost about how to tune
        # and perform the piece on the guitar.
        # TODO: this attribute doesn't exist in MEI, make a custom build
        if capo > 0:
            staff_def.addAttribute('tab.capo', str(capo))

        XmlExport.meiDocumentToFile(mei_doc, mei_path)
예제 #23
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Ungroup a neume with the provided ID into puncta.
        Create bounding box information for each punctum.
        '''

        data = json.loads(self.get_argument("data", ""))

        nids = str(data["nids"]).split(",")
        bboxes = data["bbs"]

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        newids = []
        for nid, bb in zip(nids, bboxes):
            newids.append(self.insert_puncta(nid, bb))
            self.delete_old_neume(nid)

        XmlExport.write(self.mei, fname)

        result = {"nids": newids}
        self.write(json.dumps(result))

        self.set_status(200)
예제 #24
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Change the shape of a given clef. Must also update
        bounding box data since the glyphs for c and f clefs
        are different. Must also update pitched elements on the
        affected staff to correspond with the new clef shape.
        '''

        data = json.loads(self.get_argument("data", ""))
        clef_id = str(data["id"])

        # bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        clef = self.mei.getElementById(clef_id)

        # update clef shape
        clef.addAttribute("shape", str(data["shape"]).upper())

        self.update_or_add_zone(clef, ulx, uly, lrx, lry)
        self.update_pitched_elements(data["pitchInfo"])

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #25
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a division before the given element. There is one case
        where there is no element to insert before, when there is no
        subsequent staff. In this case, the element is inserted at the end
        of the last system. Also sets the bounding box information of the new
        punctum.
        '''

        div_type = str(self.get_argument("type", ""))
        beforeid = str(self.get_argument("beforeid", None))

        # bounding box
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        zone = self.create_zone(ulx, uly, lrx, lry)
        division = self.create_new_division(div_type)
        self.add_zone(division, zone)
        self.insert_division(division, beforeid)

        XmlExport.write(self.mei, fname)

        result = {"id": division.getId()}
        self.write(json.dumps(result))
        self.set_status(200)
예제 #26
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Move a clef on a staff (must not change staff).
        Updates the bounding box information of the clef
        and updates the pitch information (pitch name and
        octave) of all pitched elements on the affected staff.
        '''

        data = json.loads(self.get_argument("data", ""))
        clef_id = str(data["id"])
        
        # bounding box
        ulx = str(data["ulx"])
        uly = str(data["uly"])
        lrx = str(data["lrx"])
        lry = str(data["lry"])

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        clef = self.mei.getElementById(clef_id)

        # update staff line the clef is on
        clef.addAttribute("line", str(data["line"]))

        self.update_or_add_zone(clef, ulx, uly, lrx, lry)
        self.update_pitched_elements(data["pitchInfo"])

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #27
0
    def sanitize_mei_str(self, mei_str, output_mei_path=None, prune=True):
        self.mei_doc = XmlImport.documentFromText(mei_str)
        self._sanitize_mei(prune)

        if output_mei_path:
            XmlExport.meiDocumentToFile(self.mei_doc, str(output_mei_path))
        else:
            return XmlExport.meiDocumentToText(self.mei_doc)
예제 #28
0
    def sanitize_mei_str(self, mei_str, output_mei_path=None, prune=True):
        self.mei_doc = XmlImport.documentFromText(mei_str)
        self._sanitize_mei(prune)

        if output_mei_path:
            XmlExport.meiDocumentToFile(self.mei_doc, str(output_mei_path))
        else:
            return XmlExport.meiDocumentToText(self.mei_doc)
예제 #29
0
    def output_mei(self, output_path):
        '''
        Write the generated mei to disk
        '''

        # output mei file
        if self.meidoc == None:
            raise Warning('The MEI document has not yet been created');
            return

        XmlExport.meiDocumentToFile(self.meidoc, output_path)
예제 #30
0
    def write_doc(self, **kwargs):
        '''
        Write the modified MEI document out to a file,
        clobbering the input file, if no filename parameter
        is provided.
        '''

        if 'filename' in kwargs:
            filename = kwargs['filename']
        else:
            filename = self.filename

        XmlExport.write(self.mei, filename)
예제 #31
0
파일: modifymei.py 프로젝트: avorio/Neon.js
    def write_doc(self, **kwargs):
        '''
        Write the modified MEI document out to a file,
        clobbering the input file, if no filename parameter
        is provided.
        '''

        if 'filename' in kwargs:
            filename = kwargs['filename']
        else:
            filename = self.filename

        XmlExport.write(self.mei, filename)
예제 #32
0
def massage_mei(in_file, out_file): 
    try:
        analysis = make_analysis(in_file)
        MEI_instructions = TransformData(
            arranger_to_editor=True,
            obliterate_incipit=analysis.first_measure_empty,
            replace_longa=True,
            editorial_resp=analysis.has_arranger_element,
            alternates_list=analysis.alternates_list)    
        old_MEI_doc = XmlImport.documentFromFile(in_file)
        new_MEI_doc = transform_mei(old_MEI_doc, MEI_instructions)
        XmlExport.meiDocumentToFile(new_MEI_doc, out_file)
    except Exception as ex:
        logging.critical(ex)
        logging.critical("Error during massaging " + in_file)
예제 #33
0
파일: models.py 프로젝트: gburlet/robotaba
    def mei_append_metamusic(self):
        '''
        Append meta data for the musical work to the mei document
        '''
    
        mei_path = self.get_abs_path()        
        mei_doc = XmlImport.documentFromFile(mei_path)

        mei = mei_doc.getRootElement()
        mei_head = MeiElement('meiHead')
        music = mei.getChildrenByName('music')[0]
        
        file_desc = MeiElement('fileDesc')

        # title
        title_stmt = MeiElement('titleStmt')
        title = MeiElement('title')
        title.setValue(str(self.fk_mid.title))

        # contributers
        resp_stmt = MeiElement('respStmt')
        pers_name_artist = MeiElement('persName')
        pers_name_artist.addAttribute('role', 'artist')
        pers_name_artist.setValue(str(self.fk_mid.artist))
        pers_name_tabber = MeiElement('persName')
        pers_name_tabber.addAttribute('role', 'tabber')
        pers_name_tabber.setValue(str(self.fk_mid.copyright))

        # encoding information
        encoding_desc = MeiElement('encodingDesc')
        app_info = MeiElement('appInfo')
        application = MeiElement('application')
        application.setValue('Robotaba')

        mei_head.addChild(file_desc)
        file_desc.addChild(title_stmt)
        title_stmt.addChild(title)
        title_stmt.addChild(resp_stmt)
        resp_stmt.addChild(pers_name_artist)
        resp_stmt.addChild(pers_name_tabber)
        title_stmt.addChild(encoding_desc)
        encoding_desc.addChild(app_info)
        app_info.addChild(application)

        # attach mei metadata to the document
        mei.addChildBefore(music, mei_head)

        XmlExport.meiDocumentToFile(mei_doc, mei_path)
예제 #34
0
    def mei_append_metamusic(self):
        '''
        Append meta data for the musical work to the mei document
        '''

        mei_path = self.get_abs_path()
        mei_doc = XmlImport.documentFromFile(mei_path)

        mei = mei_doc.getRootElement()
        mei_head = MeiElement('meiHead')
        music = mei.getChildrenByName('music')[0]

        file_desc = MeiElement('fileDesc')

        # title
        title_stmt = MeiElement('titleStmt')
        title = MeiElement('title')
        title.setValue(str(self.fk_mid.title))

        # contributers
        resp_stmt = MeiElement('respStmt')
        pers_name_artist = MeiElement('persName')
        pers_name_artist.addAttribute('role', 'artist')
        pers_name_artist.setValue(str(self.fk_mid.artist))
        pers_name_tabber = MeiElement('persName')
        pers_name_tabber.addAttribute('role', 'tabber')
        pers_name_tabber.setValue(str(self.fk_mid.copyright))

        # encoding information
        encoding_desc = MeiElement('encodingDesc')
        app_info = MeiElement('appInfo')
        application = MeiElement('application')
        application.setValue('Robotaba')

        mei_head.addChild(file_desc)
        file_desc.addChild(title_stmt)
        title_stmt.addChild(title)
        title_stmt.addChild(resp_stmt)
        resp_stmt.addChild(pers_name_artist)
        resp_stmt.addChild(pers_name_tabber)
        title_stmt.addChild(encoding_desc)
        encoding_desc.addChild(app_info)
        app_info.addChild(application)

        # attach mei metadata to the document
        mei.addChildBefore(music, mei_head)

        XmlExport.meiDocumentToFile(mei_doc, mei_path)
예제 #35
0
 def test_documentwritefailure(self):
     doc = MeiDocument()
     root = MeiElement("mei")
     root.id = "myid"
     doc.root = root
     with self.assertRaises(FileWriteFailureException) as cm:
         ret = XmlExport.meiDocumentToFile(doc, "C:/StupidPath")
     self.assertTrue(isinstance(cm.exception, FileWriteFailureException))
예제 #36
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Delete a given custos from the document.
        Also remove the element's bounding box information.
        '''
        
        custos_id = str(self.get_argument("id", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        self.delete_custos(custos_id)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #37
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Delete a given custos from the document.
        Also remove the element's bounding box information.
        '''

        custos_id = str(self.get_argument("id", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        self.delete_custos(custos_id)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #38
0
    def test_exporttostring(self):
        doc = MeiDocument()
        root = MeiElement("mei")
        root.id = "myid"
        doc.root = root

        expected = "<?xml version=\"1.0\"?>\n<mei xmlns=\"http://www.music-encoding.org/ns/mei\" xml:id=\"myid\" meiversion=\"2013\"/>\n";
        ret = XmlExport.meiDocumentToText(doc)
        self.assertEqual(expected, ret)
예제 #39
0
    def write_doc(self, **kwargs):
        '''
        Write the modified MEI document out to a file,
        clobbering the input file, if no filename parameter
        is provided.
        '''

        if 'filename' in kwargs:
            filename = kwargs['filename']
        else:
            filename = self.filename

        filename_split_initial = os.path.split(filename)
        filename_dir, mei_filename = filename_split_initial

        filename_split = os.path.split(filename_dir)
        filename_split_beg, filename_split_end = filename_split
        undo_path = filename_split_beg + "/undo/"

        file_list = [
            f for f in os.listdir(undo_path)
            if os.path.isfile(os.path.join(undo_path, f))
        ]

        file_num = 1 + len(file_list)

        mei_filename_split = os.path.splitext(mei_filename)
        mei_name, mei_ext = mei_filename_split

        if (file_num > 50):
            file_num = 50
            os.remove(undo_path + mei_name + '_01' + mei_ext)
            file_list.pop(0)
            for idx, f in enumerate(file_list):
                if (idx < 9):
                    os.rename(
                        undo_path + f,
                        undo_path + mei_name + '_0' + str(idx + 1) + mei_ext)
                else:
                    os.rename(
                        undo_path + f,
                        undo_path + mei_name + '_' + str(idx + 1) + mei_ext)

        if (file_num < 10):
            XmlExport.write(
                self.mei,
                undo_path + mei_name + '_0' + str(file_num) + mei_ext)
            XmlExport.write(self.mei, filename)
        else:
            XmlExport.write(
                self.mei, undo_path + mei_name + '_' + str(file_num) + mei_ext)
            XmlExport.write(self.mei, filename)
예제 #40
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Delete a division from the MEI document. Special
        consideration is taken when deleting divisions of form
        "final"
        '''

        division_ids = str(self.get_argument("ids", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)
        
        for id in division_ids.split(","):
            division = self.mei.getElementById(id)
            self.delete_division(division)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #41
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Delete a division from the MEI document. Special
        consideration is taken when deleting divisions of form
        "final"
        '''

        division_ids = str(self.get_argument("ids", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        for id in division_ids.split(","):
            division = self.mei.getElementById(id)
            self.delete_division(division)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #42
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a punctum before the given element. There is one case where
        there is no element to insert before, when there is no subsequent staff.
        In this case, the element is inserted at the end of the last system.
        Also sets the bounding box information of the new punctum.
        '''

        beforeid = str(self.get_argument("beforeid", None))
        pname = str(self.get_argument("pname", ""))
        oct = str(self.get_argument("oct", ""))
        dot_form = self.get_argument("dotform", None)

        # Bounding box
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        punctum = self.create_new_punctum(pname, oct, dot_form)
        zone = self.get_new_zone(ulx, uly, lrx, lry)
        self.add_zone(punctum, zone)

        if beforeid is None:
            # get last layer
            layers = self.mei.getElementsByName("layer")
            if len(layers):
                layers[-1].addChild(punctum)
        else:
            self.insert_punctum(punctum, beforeid)

        XmlExport.write(self.mei, fname)

        result = {"nid": punctum.getId()}
        self.write(json.dumps(result))
        self.set_status(200)
예제 #43
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Insert a punctum before the given element. There is one case where
        there is no element to insert before, when there is no subsequent staff.
        In this case, the element is inserted at the end of the last system.
        Also sets the bounding box information of the new punctum.
        '''

        beforeid = str(self.get_argument("beforeid", None))
        pname = str(self.get_argument("pname", ""))
        oct = str(self.get_argument("oct", ""))
        dot_form = self.get_argument("dotform", None)

        # Bounding box
        lrx = str(self.get_argument("lrx", None))
        lry = str(self.get_argument("lry", None))
        ulx = str(self.get_argument("ulx", None))
        uly = str(self.get_argument("uly", None))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        punctum = self.create_new_punctum(pname, oct, dot_form)
        zone = self.get_new_zone(ulx, uly, lrx, lry)
        self.add_zone(punctum, zone)
        
        if beforeid is None:
            # get last layer
            layers = self.mei.getElementsByName("layer")
            if len(layers):
                layers[-1].addChild(punctum)
        else:
            self.insert_punctum(punctum, beforeid)

        XmlExport.write(self.mei, fname)

        result = {"nid": punctum.getId()}
        self.write(json.dumps(result))
        self.set_status(200)
예제 #44
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        """ Delete one or more <note> or <neume> elements.
        Pass in an argument called 'id' with a comma separated list of
        ids of note elements to delete.
        If the note's surrounding <nc> element is empty after this, remove it.
        If the nc's surrounding <neume> element is empty, remove it.
        Remove any <zone> elements whose ids are referenced by removed <neume>s.

        Does not reduce the size of the bounding box on a <zone> or change the neume
        type if it now has a different number of <note> elements.
        """
        todelete = self.get_argument("ids", "")

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)

        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)
        self.do_delete(todelete)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #45
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Delete a doh or fah clef.
        Must also update pitched elements on the staff
        that are affected by the deletion of this clef
        element.
        '''

        clefs_to_delete = json.loads(self.get_argument("data", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        for c in clefs_to_delete:
            clef = self.mei.getElementById(str(c["id"]))
            self.delete_clef(clef)
            self.update_pitched_elements(c["pitchInfo"])

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #46
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        """ Delete one or more <note> or <neume> elements.
        Pass in an argument called 'id' with a comma separated list of
        ids of note elements to delete.
        If the note's surrounding <nc> element is empty after this, remove it.
        If the nc's surrounding <neume> element is empty, remove it.
        Remove any <zone> elements whose ids are referenced by removed <neume>s.

        Does not reduce the size of the bounding box on a <zone> or change the neume
        type if it now has a different number of <note> elements.
        """
        todelete = self.get_argument("ids", "")

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)

        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)
        self.do_delete(todelete)

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #47
0
파일: api.py 프로젝트: sequoiar/Neon.js
    def post(self, file):
        '''
        Delete a doh or fah clef.
        Must also update pitched elements on the staff
        that are affected by the deletion of this clef
        element.
        '''

        clefs_to_delete = json.loads(self.get_argument("data", ""))

        mei_directory = os.path.abspath(conf.MEI_DIRECTORY)
        fname = os.path.join(mei_directory, file)
        self.mei = XmlImport.read(fname)

        for c in clefs_to_delete:
            clef = self.mei.getElementById(str(c["id"]))
            self.delete_clef(clef)
            self.update_pitched_elements(c["pitchInfo"])

        XmlExport.write(self.mei, fname)

        self.set_status(200)
예제 #48
0
    def save_elite(self, score, output_path=None):
        '''
        Save the elite tablature to the specified output path, or return 
        a string representation of the MeiDocument.
        The output file should be a copy on the HDD
        of the original input file, to preserve meta-data and other 
        contents of the file not maintained in the internal representation
        of the musical document.

        PARAMETERS
        ----------
        output_path {String}: the output path of the mei file
        '''

        # get list of tablature data to append to note elements
        # plucks is a list of tuples (MeiElement.id, Pluck)
        plucks = []
        for chromo in self.elites:
            for g in chromo.genes:
                if isinstance(g.guitar_event, Pluck):
                    plucks.append((g.score_event.id, g.guitar_event))
                elif isinstance(g.guitar_event, Strum):
                    for p, n in zip(g.guitar_event.plucks, g.score_event.notes):
                        plucks.append((n.id, p))       
        
        # add the tablature data to the original mei document
        for p in plucks:
            note = score.meidoc.getElementById(p[0])
            note.addAttribute('tab.string', str(p[1].string+1))
            note.addAttribute('tab.fret', str(p[1].fret))

        if output_path is not None:
            # write the modified document to disk
            XmlExport.meiDocumentToFile(score.meidoc, output_path)
        else:
            # return a string of the MeiDocument
            return XmlExport.meiDocumentToText(score.meidoc)
예제 #49
0
    def test_exportcomment(self):
        doc = MeiDocument()
        root = MeiElement("mei")
        root.id = "myid"

        doc.root = root

        comment = MeiElement("_comment")
        comment.value = "comment"
        comment.tail = "t"

        root.addChild(comment)
        expected = "<?xml version=\"1.0\"?>\n<mei xmlns=\"http://www.music-encoding.org/ns/mei\" xml:id=\"myid\" meiversion=\"2013\"><!--comment-->t</mei>\n";
        ret = XmlExport.meiDocumentToText(doc)
        self.assertEqual(expected, ret)
예제 #50
0
    def test_exportnamespace(self):
        doc = MeiDocument()
        root = MeiElement("mei")
        root.id = "myid"
        doc.root = root

        xlink = MeiNamespace("xlink", "http://www.w3.org/1999/xlink")
        attr = MeiAttribute(xlink, "title", "my awesome thing")
        root.addAttribute(attr)

        expected = "<?xml version=\"1.0\"?>\n<mei xmlns=\"http://www.music-encoding.org/ns/mei\" \
xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:id=\"myid\" xlink:title=\"my awesome thing\" meiversion=\"2013\"/>\n";

        ret = XmlExport.meiDocumentToText(doc)
        self.assertEqual(expected, ret)
예제 #51
0
    def test_exportvalueandtail(self):
        doc = MeiDocument()
        root = MeiElement("mei")
        root.id = "myid"
        doc.root = root

        note = MeiElement("note")
        note.id = "noteid"
        note.value = "value"
        note.tail = "tail"
        root.addChild(note)

        expected = "<?xml version=\"1.0\"?>\n<mei xmlns=\"http://www.music-encoding.org/ns/mei\" xml:id=\"myid\" meiversion=\"2013\"><note xml:id=\"noteid\">value</note>tail</mei>\n";
        ret = XmlExport.meiDocumentToText(doc)

        self.assertEqual(expected, ret)
예제 #52
0
파일: modifymei.py 프로젝트: DDMAL/Neon.js
    def write_doc(self, **kwargs):
        '''
        Write the modified MEI document out to a file,
        clobbering the input file, if no filename parameter
        is provided.
        '''

        if 'filename' in kwargs:
            filename = kwargs['filename']
        else:
            filename = self.filename

        filename_split_initial = os.path.split(filename)
        filename_dir, mei_filename = filename_split_initial

        filename_split = os.path.split(filename_dir)
        filename_split_beg, filename_split_end = filename_split
        undo_path = filename_split_beg + "/undo/"

        file_list = [f for f in os.listdir(undo_path)
                        if os.path.isfile(os.path.join(undo_path, f))]

        file_num = 1 + len(file_list)

        mei_filename_split = os.path.splitext(mei_filename)
        mei_name, mei_ext = mei_filename_split

        if(file_num > 50):
            file_num = 50
            os.remove(undo_path + mei_name + '_01' + mei_ext)
            file_list.pop(0)
            for idx, f in enumerate(file_list):
                if(idx < 9):
                    os.rename(undo_path + f, undo_path + mei_name + '_0' + str(idx + 1) + mei_ext)
                else:
                    os.rename(undo_path + f, undo_path + mei_name + '_' + str(idx + 1) + mei_ext)

        if (file_num < 10):
            XmlExport.write(self.mei, undo_path + mei_name + '_0' + str(file_num) + mei_ext)
            XmlExport.write(self.mei, filename)
        else:
            XmlExport.write(self.mei, undo_path + mei_name + '_' + str(file_num) + mei_ext)
            XmlExport.write(self.mei, filename)
예제 #53
0
    def write_mei(self, notes, output_path=None):
        # begin constructing mei document
        meidoc = MeiDocument()
        mei = MeiElement('mei')
        meidoc.setRootElement(mei)
        mei_head = MeiElement('meiHead')
        mei.addChild(mei_head)

        music = MeiElement('music')
        body = MeiElement('body')
        mdiv = MeiElement('mdiv')
        score = MeiElement('score')
        score_def = MeiElement('scoreDef')

        # assume 4/4 time signature
        meter_count = 4
        meter_unit = 4
        score_def.addAttribute('meter.count', str(meter_count))
        score_def.addAttribute('meter.unit', str(meter_unit))

        staff_def = MeiElement('staffDef')
        staff_def.addAttribute('n', '1')
        staff_def.addAttribute('label.full', 'Electric Guitar')
        staff_def.addAttribute('clef.shape', 'TAB')

        instr_def = MeiElement('instrDef')
        instr_def.addAttribute('n', 'Electric_Guitar')
        instr_def.addAttribute('midi.channel', '1')
        instr_def.addAttribute('midi.instrnum', '28')

        mei.addChild(music)
        music.addChild(body)
        body.addChild(mdiv)
        mdiv.addChild(score)
        score.addChild(score_def)
        score_def.addChild(staff_def)
        staff_def.addChild(instr_def)

        section = MeiElement('section')
        score.addChild(section)
        # another score def
        score_def = MeiElement('scoreDef')
        score_def.addAttribute('meter.count', str(meter_count))
        score_def.addAttribute('meter.unit', str(meter_unit))
        section.addChild(score_def)

        # start writing pitches to file
        note_container = None
        for i, frame_n in enumerate(notes):
            if i % meter_count == 0:
                measure = MeiElement('measure')
                measure.addAttribute('n', str(int(i / meter_count + 1)))
                staff = MeiElement('staff')
                staff.addAttribute('n', '1')
                layer = MeiElement('layer')
                layer.addAttribute('n', '1')
                section.addChild(measure)
                measure.addChild(staff)
                staff.addChild(layer)
                note_container = layer

            if len(frame_n) > 1:
                chord = MeiElement('chord')
                for n in frame_n:
                    note = MeiElement('note')
                    pname = n['pname'][0].upper()
                    note.addAttribute('pname', pname)
                    note.addAttribute('oct', str(n['oct']))
                    if len(n['pname']) > 1 and n['pname'][1] == '#':
                        # there is an accidental
                        note.addAttribute('accid.ges', 's')
                    note.addAttribute('dur', str(meter_unit))
                    chord.addChild(note)
                note_container.addChild(chord)
            else:
                n = frame_n[0]
                note = MeiElement('note')
                pname = n['pname'][0].upper()
                note.addAttribute('pname', pname)
                note.addAttribute('oct', str(n['oct']))
                if len(n['pname']) > 1 and n['pname'][1] == '#':
                    # there is an accidental
                    note.addAttribute('accid.ges', 's')
                note.addAttribute('dur', str(meter_unit))
                note_container.addChild(note)

        if output_path is not None:
            XmlExport.meiDocumentToFile(meidoc, output_path)
        else:
            return XmlExport.meiDocumentToText(meidoc)
예제 #54
0
    def __init__(self, incoming_data, original_image, page_number=None):
        self._recognition_results = incoming_data
        # self.mei = mod.mei_()
        self.mei = MeiElement("mei")
        self.staff = None

        # Hack: I'm not sure what staff_num is. In any case it's strange to set it to None.
        # I therefore set it to 0 if page_number is None.
        if page_number is not None:
            self.staff_num = int(page_number)
        else:
            self.staff_num = 0
        self.glyph = None

        self._note_elements = None
        self._neume_pitches = []

        # set up a basic MEI document structure

        # header
        # self.meihead = mod.meiHead_()
        self.meihead = MeiElement("meiHead")
        # self.filedesc = mod.fileDesc_()
        self.filedesc = MeiElement("fileDesc")
        # self.titlestmt = mod.titleStmt_()
        self.titlestmt = MeiElement("titleStmt")
        # self.title = mod.title_()
        self.title = MeiElement("title")
        # self.pubstmt = mod.pubStmt_()
        self.pubstmt = MeiElement("pubStmt")

        self.titlestmt.addChild(self.title)

        self.filedesc.addChild(self.titlestmt)
        self.filedesc.addChild(self.pubstmt)

        self.meihead.addChild(self.filedesc)
        self.mei.addChild(self.meihead)

        # music
        # self.music = mod.music_()
        self.music = MeiElement("music")
        self.facsimile = self._create_facsimile_element()
        self.surface = self._create_surface_element()
        self.graphic = self._create_graphic_element(original_image)
        lg.debug("SELF GRAPHIC:{0}".format(
            XmlExport.meiElementToText(self.graphic)))

        self.surface.addChild(self.graphic)
        self.facsimile.addChild(self.surface)
        self.music.addChild(self.facsimile)

        self.layout = self._create_layout_element()
        self.pg = self._create_page_element()
        if page_number:
            # self.pg.attributes = {"n": page_number}
            self.pg.addAttribute("n", page_number)

        self.layout.addChild(self.pg)
        self.music.addChild(self.layout)

        # self.body = mod.body_()
        self.body = MeiElement("body")
        self.music.addChild(self.body)

        self.mdiv = MeiElement("mdiv")
        # self.mdiv = mod.mdiv_()
        self.mdiv.addAttribute("type", "solesmes")
        self.body.addChild(self.mdiv)

        # self.score = mod.score_()
        self.score = MeiElement("score")
        self.mdiv.addChild(self.score)

        # self.scoredef = mod.scoreDef_()
        self.scoredef = MeiElement("scoreDef")
        self.score.addChild(self.scoredef)

        # self.section = mod.section_()
        self.section = MeiElement("section")
        self.pagebreak = self._create_pb_element()
        # self.pagebreak.attributes = {"pageref": self.pg.id}
        self.pagebreak.addAttribute("pageref", self.pg.id)

        self.section.addChild(self.pagebreak)
        self.score.addChild(self.section)

        self.staffgrp = self._create_staffgrp_element()
        self.staffdef = self._create_staffdef_element()
        self.staffdef.addAttribute("n", str(self.staff_num))  # trouble

        self.staffgrp.addChild(self.staffdef)
        self.scoredef.addChild(self.staffgrp)

        self.layer = self._create_layer_element()
        self.layer.addAttribute("n", "1")

        self.staffel = self._create_staff_element()
        self.staffel.addAttribute("n", str(self.staff_num))  # trouble
        self.section.addChild(self.staffel)
        self.staffel.addChild(self.layer)

        for sysnum in sorted(self._recognition_results.keys()):
            syst = self._recognition_results[sysnum]
            lg.debug("sysnum:{0}".format(sysnum))
            self.system = syst
            self.systembreak = self._parse_system(sysnum, syst)
            # z = mod.zone_()
            z = MeiElement("zone")
            # z.id = self._idgen()
            # z.attributes = {'ulx': self.system['coord'][0], 'uly': self.system['coord'][1], \
            #                     'lrx': self.system['coord'][2], 'lry': self.system['coord'][3]}
            z.addAttribute("ulx", str(self.system['coord'][0]))
            z.addAttribute("uly", str(self.system['coord'][1]))
            z.addAttribute("lrx", str(self.system['coord'][2]))
            z.addAttribute("lry", str(self.system['coord'][3]))
            self.surface.addChild(z)
            # self.system.facs = z.id
            s = self._create_system_element()
            s.facs = z.id
            s.addAttribute("facs", s.facs)
            self.pg.addChild(s)
            self.systembreak.addAttribute("systemref", s.id)

        self.mei.addChild(self.music)

        # if not self.staffel.descendants_by_name('neume'):
        if not self.staffel.getDescendantsByName("neume"):
            self.staffgrp.removeChild(self.staffdef)
            self.section.removeChild(self.staffel)

        # self.md = MeiDocument.MeiDocument()
        # self.md.addelement(self.mei)
        self.md = MeiDocument()
        self.md.setRootElement(self.mei)
        print XmlExport.meiElementToText(
            self.md.getElementById(self.graphic.getId()))