NoteWorthy Composer Forum

Forums => Tips & Tricks => User Tools => Topic started by: jdorocak on 2009-07-03 02:59 am

Title: nwcPythonTxt to xml converter
Post by: jdorocak on 2009-07-03 02:59 am
Here is a Python script I wrote after reading NWC Virtuoso, kahman's post:
Python NWCTXT parser - https://forum.noteworthycomposer.com/?topic=6097.0 (https://forum.noteworthycomposer.com/?topic=6097.0)
My script converts kahman's Python List/Dictionary output to XML. I did it so that I could study the structure of an nwctxt file using a data folding text editor. The XML structure is my own home grown version based on what I inferred from kahman's Python Data Structure. I have done minimal testing so use it with caution. Please let me know what you think. Please post any additions here. You can use this script as you like. Here is the code:

Code: [Select · Download]
"""
nwcPy2nwcXml.py Translates
FROM: nwcPythonListDictFormat (kahman's nwctxt to python converter pyNWC-a output)
TO: jdorocak's homegrown xml (So I can use data folding in a text editor.) :)

Usage:   nwcPy2nwcXml.py infileName  outfileName
Example: nwcPy2nwcXml.py mySong.py   mySong.xml
Author:  Joe Dorocak
License: Use this as you please. :)
         Use with caution - I have done minimal testing. No warranty is implied. :)
"""

class ConvertToXML():
    """
    Converts
        FROM: nwcPythonListDictFormat (NWC Virtuoso kahman's nwctxt to python converter pyNWC-a output)
        TO: jdorocak's homegrown xml (So I can use data folding in a text editor.) :)
    rs == resultString; il == indentationLevel; aprs(il,str) == appendToResultString(indentationLevel,strToAppend)
    data == string output of kahman's nwctxt to python converter
    ix == index of current pythonListDict item;
    joe's xml syntax for nwctxtPy files inferred from analysis of data (i added elements named j*):

    <jNwctxtPy>
        <SongInfo count=1></SongInfo>
        <PgSetup count=1></PgSetup>
        <jFonts><Font count=12></Font></jFonts>
        <PgMargins count=1></PgMargins>
        <jStaves>
            <jStaff>
                <AddStaff count=1></AddStaff>
                <StaffProperties count=2></StaffProperties>
                <StaffInstrument count=1></StaffInstrument>
                <Clef count=n></Clef> 
                <Key count=n></Key>
                <Tempo count=n></Tempo>
                <Note count=n></Note>
                <Chord count=n></Chord>
                <Bar count=n></Bar>
            </jStaff>
    </jStaves>
    </jNwctxtPy>
    """
    def __init__(self, indata):
        """
        data == data to be converted.  FROM: nwcPythonListDictFormat (kahman's nwctxt to python converter pyNWC-a output)
        rs == resultString; converted data jdorocak's homegrown xml (So I can use data folding in a text editor.) :)
        """
        self.data = eval(indata)
        self.data.append(['End', {'Joe': 'End', 'Pos': 'Whatever'}])
        self.rs = ''         

    def toxml(self):
        self.aprs(0,'<jNwctxtPy>')


        #SongInfo
        self.aprs(1,'<SongInfo count=1>')
        ix = 0
        print len(self.data)
        for k,v in self.data[ix][1].iteritems():
            self.aprs (2,'<' + k + '>' + str(v) + '</' + k + '>')
        self.aprs (1,'</SongInfo>')

        #PgSetup
        self.aprs (1,'<PgSetup count=1>')
        ix = 1
        for k,v in self.data[ix][1].iteritems():
            self.aprs (2,'<' + k + '>' + str(v) + '</' + k + '>'   )
        self.aprs (1,'</PgSetup>')

        #Fonts
        self.aprs (1,'<jFonts>')
        for ix in range(2,14):
            self.aprs (2,'<Font count=12>')
            for k,v in self.data[ix][1].iteritems():
                self.aprs (3,'<' + k + '>' + str(v) + '</' + k + '>'   )
            self.aprs (2,'</Font>')
        self.aprs (1,'</jFonts>')

        #PgMargins
        self.aprs (1,'<PgSetup count=1>')
        ix = 15
        for k,v in self.data[ix][1].iteritems():
            self.aprs (2,'<' + k + '>' + str(v) + '</' + k + '>'   )
        self.aprs (1,'</PgSetup>')



        self.aprs (1,'<jStaves>')
        self.aprs (2,'<jStaff>')
        #AddStaff
        ix = 16
        for ix in range(ix,len(self.data)-1):
            #if self.data[ix+1][0] == 'AddStaff': self.aprs (2,'<jStaff>')    #ix+1 needed to add ['End',{'Joe':'whatever'}]
            self.aprs (3,'<'+ self.data[ix][0] +'>')
            for k,v in self.data[ix][1].iteritems():
                self.aprs (4,'<' + k + '>' + str(v) + '</' + k + '>'   )
            self.aprs (3,'</'+ self.data[ix][0] +'>')
            if self.data[ix+1][0] == 'AddStaff': #ix+1 needed to add ['End',{'Joe':'whatever'}]
                self.aprs (2,'</jStaff>')  
                self.aprs (2,'<jStaff>')

        self.aprs (2,'</jStaff>')
        self.aprs (1,'</jStaves>')


        self.aprs(0,'</jNwctxtPy>')
        return self.rs

    def aprs(self, il, strToAppend):
        """aprs(il,str) == appendToResultString(indentationLevel,strToAppend)"""
        self.rs = ''.join([self.rs, il*2*' '+strToAppend+'\n'])
        #print il*2*' '+strToAppend
   

import sys

N_ARGS = 2 

def main(argv=None):
    if argv == None: argv=sys.argv
    args = argv[1:]  #NOTE: args[0] != argv[0] == <full path to example.py>
    if len(args) != N_ARGS or "-h" in args or "--help" in args:
        print __doc__
        sys.exit(2)

    f = open(args[0], 'r'); s = f.read(); f.close()          # get the input file into s
    cx = ConvertToXML(s)                                     # make a new converter for s
    sXml = cx.toxml()                                        # translate s into sXml
    f = open(args[1], 'w'); f.write(sXml); f.close()    # write str(s2) into the output file
    print 'Translated ' + str(args[0]) + ' yielding ' + str(args[1])


if __name__ == '__main__':
    sys.exit(main())


I have posted the addition I did to kahman's code to save his output in a file, at his post: https://forum.noteworthycomposer.com/?topic=6097.0 (https://forum.noteworthycomposer.com/?topic=6097.0)


All the best. :)
Joe